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.

ExportDataGenerator   D
last analyzed

Complexity

Total Complexity 58

Size/Duplication

Total Lines 671
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 58
eloc 336
c 2
b 0
f 0
dl 0
loc 671
rs 4.5599

24 Methods

Rating   Name   Duplication   Size   Complexity  
A exportTags() 0 34 3
A exportCategories() 0 32 2
A exportBudgets() 0 48 3
A exportPiggies() 0 48 5
A mergeTags() 0 11 3
A setExportBills() 0 3 1
D export() 0 32 10
A setExportRecurring() 0 3 1
A setUser() 0 3 1
A exportRules() 0 51 4
A setExportCategories() 0 3 1
A setExportTags() 0 3 1
A setExportPiggies() 0 3 1
A __construct() 0 14 1
A setEnd() 0 3 1
A setExportRules() 0 3 1
A exportTransactions() 0 54 2
A setExportAccounts() 0 3 1
A exportBills() 0 38 2
A setStart() 0 3 1
A exportAccounts() 0 43 3
A setExportTransactions() 0 3 1
B exportRecurring() 0 82 8
A setExportBudgets() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like ExportDataGenerator often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ExportDataGenerator, and based on these observations, apply Extract Interface, too.

1
<?php
2
declare(strict_types=1);
3
/**
4
 * ExportDataGenerator.php
5
 * Copyright (c) 2019 [email protected]
6
 *
7
 * This file is part of Firefly III (https://github.com/firefly-iii).
8
 *
9
 * This program is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Affero General Public License as
11
 * published by the Free Software Foundation, either version 3 of the
12
 * License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU Affero General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Affero General Public License
20
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
21
 */
22
23
namespace FireflyIII\Support\Export;
24
25
use Carbon\Carbon;
26
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
27
use FireflyIII\Models\Account;
28
use FireflyIII\Models\Bill;
29
use FireflyIII\Models\Budget;
30
use FireflyIII\Models\BudgetLimit;
31
use FireflyIII\Models\Category;
32
use FireflyIII\Models\PiggyBank;
33
use FireflyIII\Models\Recurrence;
34
use FireflyIII\Models\RecurrenceRepetition;
35
use FireflyIII\Models\RecurrenceTransaction;
36
use FireflyIII\Models\Rule;
37
use FireflyIII\Models\RuleAction;
38
use FireflyIII\Models\RuleTrigger;
39
use FireflyIII\Models\Tag;
40
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
41
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
42
use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
43
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
44
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
45
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
46
use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface;
47
use FireflyIII\Repositories\Rule\RuleRepositoryInterface;
48
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
49
use FireflyIII\User;
50
use League\Csv\Writer;
51
52
/**
53
 * Class ExportDataGenerator
54
 */
55
class ExportDataGenerator
56
{
57
    /** @var Carbon */
58
    private $end;
59
    /** @var bool */
60
    private $exportTransactions;
61
    /** @var Carbon */
62
    private $start;
63
    /** @var bool */
64
    private $exportAccounts;
65
    /** @var bool */
66
    private $exportBudgets;
67
    /** @var bool */
68
    private $exportCategories;
69
    /** @var bool */
70
    private $exportTags;
71
    /** @var bool */
72
    private $exportRecurring;
73
    /** @var bool */
74
    private $exportRules;
75
    /** @var bool */
76
    private $exportBills;
77
    /** @var bool */
78
    private $exportPiggies;
79
80
    /** @var User */
81
    private $user;
82
83
    public function __construct()
84
    {
85
        $this->start = new Carbon;
86
        $this->start->subYear();
87
        $this->end                = new Carbon;
88
        $this->exportTransactions = false;
89
        $this->exportAccounts     = false;
90
        $this->exportBudgets      = false;
91
        $this->exportCategories   = false;
92
        $this->exportTags         = false;
93
        $this->exportRecurring    = false;
94
        $this->exportRules        = false;
95
        $this->exportBills        = false;
96
        $this->exportPiggies      = false;
97
    }
98
99
    /**
100
     * @param User $user
101
     */
102
    public function setUser(User $user): void
103
    {
104
        $this->user = $user;
105
    }
106
107
    /**
108
     * @return array
109
     * @throws \League\Csv\CannotInsertRecord
110
     */
111
    public function export(): array
112
    {
113
        $return = [];
114
        if ($this->exportAccounts) {
115
            $return['accounts'] = $this->exportAccounts();
116
        }
117
        if ($this->exportBills) {
118
            $return['bills'] = $this->exportBills();
119
        }
120
        if ($this->exportBudgets) {
121
            $return['budgets'] = $this->exportBudgets();
122
        }
123
        if ($this->exportCategories) {
124
            $return['categories'] = $this->exportCategories();
125
        }
126
        if ($this->exportPiggies) {
127
            $return['piggies'] = $this->exportPiggies();
128
        }
129
        if ($this->exportRecurring) {
130
            $return['recurrences'] = $this->exportRecurring();
131
        }
132
        if ($this->exportRules) {
133
            $return['rules'] = $this->exportRules();
134
        }
135
        if ($this->exportTags) {
136
            $return['tags'] = $this->exportTags();
137
        }
138
        if ($this->exportTransactions) {
139
            $return['transactions'] = $this->exportTransactions();
140
        }
141
142
        return $return;
143
    }
144
145
    /**
146
     * @param bool $exportAccounts
147
     */
148
    public function setExportAccounts(bool $exportAccounts): void
149
    {
150
        $this->exportAccounts = $exportAccounts;
151
    }
152
153
    /**
154
     * @param bool $exportBudgets
155
     */
156
    public function setExportBudgets(bool $exportBudgets): void
157
    {
158
        $this->exportBudgets = $exportBudgets;
159
    }
160
161
    /**
162
     * @param bool $exportCategories
163
     */
164
    public function setExportCategories(bool $exportCategories): void
165
    {
166
        $this->exportCategories = $exportCategories;
167
    }
168
169
    /**
170
     * @param bool $exportTags
171
     */
172
    public function setExportTags(bool $exportTags): void
173
    {
174
        $this->exportTags = $exportTags;
175
    }
176
177
    /**
178
     * @param bool $exportRecurring
179
     */
180
    public function setExportRecurring(bool $exportRecurring): void
181
    {
182
        $this->exportRecurring = $exportRecurring;
183
    }
184
185
    /**
186
     * @param bool $exportRules
187
     */
188
    public function setExportRules(bool $exportRules): void
189
    {
190
        $this->exportRules = $exportRules;
191
    }
192
193
    /**
194
     * @param bool $exportBills
195
     */
196
    public function setExportBills(bool $exportBills): void
197
    {
198
        $this->exportBills = $exportBills;
199
    }
200
201
    /**
202
     * @param bool $exportPiggies
203
     */
204
    public function setExportPiggies(bool $exportPiggies): void
205
    {
206
        $this->exportPiggies = $exportPiggies;
207
    }
208
209
    /**
210
     * @param Carbon $end
211
     */
212
    public function setEnd(Carbon $end): void
213
    {
214
        $this->end = $end;
215
    }
216
217
    /**
218
     * @param bool $exportTransactions
219
     */
220
    public function setExportTransactions(bool $exportTransactions): void
221
    {
222
        $this->exportTransactions = $exportTransactions;
223
    }
224
225
    /**
226
     * @param Carbon $start
227
     */
228
    public function setStart(Carbon $start): void
229
    {
230
        $this->start = $start;
231
    }
232
233
    /**
234
     * @return string
235
     */
236
    private function exportRules(): string
237
    {
238
        $header    = ['user_id', 'rule_id', 'row_contains', 'created_at', 'updated_at', 'group_id', 'group_name', 'title', 'description', 'order', 'active',
239
                      'stop_processing', 'strict', 'trigger_type', 'trigger_value', 'trigger_order', 'trigger_active', 'trigger_stop_processing', 'action_type',
240
                      'action_value', 'action_order', 'action_active', 'action_stop_processing',];
241
        $ruleRepos = app(RuleRepositoryInterface::class);
242
        $ruleRepos->setUser($this->user);
243
        $rules   = $ruleRepos->getAll();
244
        $records = [];
245
        /** @var Rule $rule */
246
        foreach ($rules as $rule) {
247
            $records[] = [
248
                $this->user->id, $rule->id, 'rule',
249
                $rule->created_at->toAtomString(), $rule->updated_at->toAtomString(),
250
                $rule->ruleGroup->id, $rule->ruleGroup->name,
251
                $rule->title, $rule->description, $rule->order, $rule->active, $rule->stop_processing, $rule->strict,
252
            ];
253
            /** @var RuleTrigger $trigger */
254
            foreach ($rule->ruleTriggers as $trigger) {
255
                $records[] = [
256
                    $this->user->id, $rule->id, 'trigger',
257
                    null, null,
258
                    null, null,
259
                    null, null, null, null, null, null,
260
                    $trigger->trigger_type, $trigger->trigger_value, $trigger->order, $trigger->active, $trigger->stop_processing,
261
                ];
262
            }
263
264
            /** @var RuleAction $action */
265
            foreach ($rule->ruleActions as $action) {
266
                $records[] = [
267
                    $this->user->id, $rule->id, 'action',
268
                    null, null,
269
                    null, null,
270
                    null, null, null, null, null, null,
271
                    null, null, null, null, null,
272
                    $action->action_type, $action->action_value, $action->order, $action->active, $action->stop_processing,
273
                ];
274
            }
275
        }
276
277
        //load the CSV document from a string
278
        $csv = Writer::createFromString('');
279
280
        //insert the header
281
        $csv->insertOne($header);
282
283
        //insert all the records
284
        $csv->insertAll($records);
285
286
        return $csv->getContent(); //returns the CSV document as a string
287
    }
288
289
    /**
290
     * @return string
291
     */
292
    private function exportAccounts(): string
293
    {
294
        $header = ['user_id', 'account_id', 'created_at', 'updated_at', 'type', 'name', 'virtual_balance', 'iban', 'number', 'active', 'currency_code', 'role',
295
                   'cc_type', 'cc_payment_date', 'in_net_worth', 'interest', 'interest_period',];
296
        /** @var AccountRepositoryInterface $repository */
297
        $repository = app(AccountRepositoryInterface::class);
298
        $repository->setUser($this->user);
299
        $accounts = $repository->getAccountsByType([]);
300
        $records  = [];
301
        /** @var Account $account */
302
        foreach ($accounts as $account) {
303
            $currency  = $repository->getAccountCurrency($account);
304
            $records[] = [
305
                $this->user->id,
306
                $account->id,
307
                $account->created_at->toAtomString(),
308
                $account->updated_at->toAtomString(),
309
                $account->accountType->type,
310
                $account->name,
311
                $account->virtual_balance,
312
                $account->iban,
313
                $account->account_number,
314
                $account->active,
315
                $currency ? $currency->code : null,
316
                $repository->getMetaValue($account, 'account_role'),
317
                $repository->getMetaValue($account, 'cc_type'),
318
                $repository->getMetaValue($account, 'cc_monthly_payment_date'),
319
                $repository->getMetaValue($account, 'include_net_worth'),
320
                $repository->getMetaValue($account, 'interest'),
321
                $repository->getMetaValue($account, 'interest_period'),
322
            ];
323
        }
324
325
        //load the CSV document from a string
326
        $csv = Writer::createFromString('');
327
328
        //insert the header
329
        $csv->insertOne($header);
330
331
        //insert all the records
332
        $csv->insertAll($records);
333
334
        return $csv->getContent(); //returns the CSV document as a string
335
    }
336
337
    /**
338
     * @return string
339
     */
340
    private function exportBills(): string
341
    {
342
        /** @var BillRepositoryInterface $repository */
343
        $repository = app(BillRepositoryInterface::class);
344
        $repository->setUser($this->user);
345
        $bills   = $repository->getBills();
346
        $header  = ['user_id', 'bill_id', 'created_at', 'updated_at', 'currency_code', 'name', 'amount_min', 'amount_max', 'date', 'repeat_freq', 'skip',
347
                    'active',];
348
        $records = [];
349
350
        /** @var Bill $bill */
351
        foreach ($bills as $bill) {
352
            $records[] = [
353
                $this->user->id,
354
                $bill->id,
355
                $bill->created_at->toAtomString(),
356
                $bill->updated_at->toAtomString(),
357
                $bill->transactionCurrency->code,
358
                $bill->name,
359
                $bill->amount_min,
360
                $bill->amount_max,
361
                $bill->date->format('Y-m-d'),
362
                $bill->repeat_freq,
363
                $bill->skip,
364
                $bill->active,
365
            ];
366
        }
367
368
        //load the CSV document from a string
369
        $csv = Writer::createFromString('');
370
371
        //insert the header
372
        $csv->insertOne($header);
373
374
        //insert all the records
375
        $csv->insertAll($records);
376
377
        return $csv->getContent(); //returns the CSV document as a string
378
    }
379
380
    /**
381
     * @return string
382
     * @throws \League\Csv\CannotInsertRecord
383
     */
384
    private function exportBudgets(): string
385
    {
386
        $header = [
387
            'user_id',
388
            'budget_id',
389
            'name',
390
            'active',
391
            'order',
392
            'start_date',
393
            'end_date',
394
            'currency_code',
395
            'amount',
396
        ];
397
398
        $budgetRepos = app(BudgetRepositoryInterface::class);
399
        $budgetRepos->setUser($this->user);
400
        $limitRepos = app(BudgetLimitRepositoryInterface::class);
401
        $budgets    = $budgetRepos->getBudgets();
402
        $records    = [];
403
        /** @var Budget $budget */
404
        foreach ($budgets as $budget) {
405
            $limits = $limitRepos->getBudgetLimits($budget);
406
            /** @var BudgetLimit $limit */
407
            foreach ($limits as $limit) {
408
                $records[] = [
409
                    $this->user->id,
410
                    $budget->id,
411
                    $budget->name,
412
                    $budget->active,
413
                    $budget->order,
414
                    $limit->start_date->format('Y-m-d'),
415
                    $limit->end_date->format('Y-m-d'),
416
                    $limit->transactionCurrency->code,
417
                    $limit->amount,
418
                ];
419
            }
420
        }
421
422
        //load the CSV document from a string
423
        $csv = Writer::createFromString('');
424
425
        //insert the header
426
        $csv->insertOne($header);
427
428
        //insert all the records
429
        $csv->insertAll($records);
430
431
        return $csv->getContent(); //returns the CSV document as a string
432
433
    }
434
435
    /**
436
     * @return string
437
     */
438
    private function exportCategories(): string
439
    {
440
        $header = ['user_id', 'category_id', 'created_at', 'updated_at', 'name'];
441
442
        /** @var CategoryRepositoryInterface $catRepos */
443
        $catRepos = app(CategoryRepositoryInterface::class);
444
        $catRepos->setUser($this->user);
445
446
        $records    = [];
447
        $categories = $catRepos->getCategories();
448
449
        /** @var Category $category */
450
        foreach ($categories as $category) {
451
            $records[] = [
452
                $this->user->id,
453
                $category->id,
454
                $category->created_at->toAtomString(),
455
                $category->updated_at->toAtomString(),
456
                $category->name,
457
            ];
458
        }
459
460
        //load the CSV document from a string
461
        $csv = Writer::createFromString('');
462
463
        //insert the header
464
        $csv->insertOne($header);
465
466
        //insert all the records
467
        $csv->insertAll($records);
468
469
        return $csv->getContent(); //returns the CSV document as a string
470
    }
471
472
    /**
473
     * @return string
474
     */
475
    private function exportPiggies(): string
476
    {
477
        /** @var PiggyBankRepositoryInterface $piggyRepos */
478
        $piggyRepos = app(PiggyBankRepositoryInterface::class);
479
        $piggyRepos->setUser($this->user);
480
481
        /** @var AccountRepositoryInterface $accountRepos */
482
        $accountRepos = app(AccountRepositoryInterface::class);
483
        $accountRepos->setUser($this->user);
484
485
        $header  = ['user_id', 'piggy_bank_id', 'created_at', 'updated_at', 'account_name', 'account_type', 'name',
486
                    'currency_code', 'target_amount', 'current_amount', 'start_date', 'target_date', 'order',
487
                    'active'];
488
        $records = [];
489
        $piggies = $piggyRepos->getPiggyBanks();
490
491
        /** @var PiggyBank $piggy */
492
        foreach ($piggies as $piggy) {
493
            $repetition = $piggyRepos->getRepetition($piggy);
494
            $currency   = $accountRepos->getAccountCurrency($piggy->account);
495
            $records[]  = [
496
                $this->user->id,
497
                $piggy->id,
498
                $piggy->created_at->toAtomString(),
499
                $piggy->updated_at->toAtomString(),
500
                $piggy->account->name,
501
                $piggy->account->accountType->type,
502
                $piggy->name,
503
                $currency ? $currency->code : null,
504
                $piggy->targetamount,
505
                $repetition ? $repetition->currentamount : null,
506
                $piggy->startdate->format('Y-m-d'),
507
                $piggy->targetdate ? $piggy->targetdate->format('Y-m-d') : null,
508
                $piggy->order,
509
                $piggy->active,
510
            ];
511
        }
512
513
        //load the CSV document from a string
514
        $csv = Writer::createFromString('');
515
516
        //insert the header
517
        $csv->insertOne($header);
518
519
        //insert all the records
520
        $csv->insertAll($records);
521
522
        return $csv->getContent(); //returns the CSV document as a string
523
    }
524
525
    /**
526
     * @return string
527
     */
528
    private function exportRecurring(): string
529
    {
530
        /** @var RecurringRepositoryInterface $recurringRepos */
531
        $recurringRepos = app(RecurringRepositoryInterface::class);
532
        $recurringRepos->setUser($this->user);
533
        $header      = [
534
            // recurrence:
535
            'user_id', 'recurrence_id', 'row_contains', 'created_at', 'updated_at', 'type', 'title', 'description', 'first_date', 'repeat_until',
536
            'latest_date', 'repetitions', 'apply_rules', 'active',
537
538
            // repetition info:
539
            'type', 'moment', 'skip', 'weekend',
540
            // transactions + meta:
541
            'currency_code', 'foreign_currency_code', 'source_name', 'source_type', 'destination_name', 'destination_type', 'amount', 'foreign_amount',
542
            'category', 'budget', 'piggy_bank', 'tags',
543
        ];
544
        $records     = [];
545
        $recurrences = $recurringRepos->getAll();
546
        /** @var Recurrence $recurrence */
547
        foreach ($recurrences as $recurrence) {
548
            // add recurrence:
549
            $records[] = [
550
                $this->user->id,
551
                $recurrence->id,
552
                'recurrence',
553
                $recurrence->created_at->toAtomString(),
554
                $recurrence->updated_at->toAtomString(),
555
                $recurrence->transactionType->type,
556
                $recurrence->title,
557
                $recurrence->description,
558
                $recurrence->first_date ? $recurrence->first_date->format('Y-m-d') : null,
559
                $recurrence->repeat_until ? $recurrence->repeat_until->format('Y-m-d') : null,
560
                $recurrence->latest_date ? $recurrence->repeat_until->format('Y-m-d') : null,
561
                $recurrence->repetitions,
562
                $recurrence->apply_rules,
563
                $recurrence->active,
564
            ];
565
            // add new row for each repetition
566
            /** @var RecurrenceRepetition $repetition */
567
            foreach ($recurrence->recurrenceRepetitions as $repetition) {
568
                $records[] = [
569
                    // recurrence
570
                    $this->user->id,
571
                    $recurrence->id, 'repetition', null, null, null, null, null, null, null, null, null, null, null,
572
573
                    // repetition:
574
                    $repetition->repetition_type, $repetition->repetition_moment, $repetition->repetition_skip, $repetition->weekend,
575
                ];
576
            }
577
            /** @var RecurrenceTransaction $transaction */
578
            foreach ($recurrence->recurrenceTransactions as $transaction) {
579
                $categoryName = $recurringRepos->getCategory($transaction);
580
                $budgetId     = $recurringRepos->getBudget($transaction);
581
                $piggyBankId  = $recurringRepos->getPiggyBank($transaction);
582
                $tags         = $recurringRepos->getTags($transaction);
583
584
                $records[] = [
585
                    // recurrence
586
                    $this->user->id,
587
                    $recurrence->id, 'transaction', null, null, null, null, null, null, null, null, null, null, null,
588
589
                    // repetition:
590
                    null, null, null, null,
591
592
                    // transaction:
593
                    $transaction->transactionCurrency->code, $transaction->foreignCurrency ? $transaction->foreignCurrency->code : null,
594
                    $transaction->sourceAccount->name, $transaction->sourceAccount->accountType->type, $transaction->destinationAccount->name,
595
                    $transaction->destinationAccount->accountType->type, $transaction->amount, $transaction->foreign_amount,
596
                    $categoryName, $budgetId, $piggyBankId, implode(',', $tags),
597
                ];
598
            }
599
        }
600
        //load the CSV document from a string
601
        $csv = Writer::createFromString('');
602
603
        //insert the header
604
        $csv->insertOne($header);
605
606
        //insert all the records
607
        $csv->insertAll($records);
608
609
        return $csv->getContent(); //returns the CSV document as a string
610
    }
611
612
    /**
613
     * @return string
614
     */
615
    private function exportTags(): string
616
    {
617
        $header = ['user_id', 'tag_id', 'created_at', 'updated_at', 'tag', 'date', 'description', 'latitude', 'longitude', 'zoom_level'];
618
619
        $tagRepos = app(TagRepositoryInterface::class);
620
        $tagRepos->setUser($this->user);
621
        $tags    = $tagRepos->get();
622
        $records = [];
623
        /** @var Tag $tag */
624
        foreach ($tags as $tag) {
625
            $records[] = [
626
                $this->user->id,
627
                $tag->id,
628
                $tag->created_at->toAtomString(),
629
                $tag->updated_at->toAtomString(),
630
                $tag->tag,
631
                $tag->date ? $tag->date->format('Y-m-d') : null,
632
                $tag->description,
633
                $tag->latitude,
634
                $tag->longitude,
635
                $tag->zoomLevel,
636
            ];
637
        }
638
639
        //load the CSV document from a string
640
        $csv = Writer::createFromString('');
641
642
        //insert the header
643
        $csv->insertOne($header);
644
645
        //insert all the records
646
        $csv->insertAll($records);
647
648
        return $csv->getContent(); //returns the CSV document as a string
649
    }
650
651
    /**
652
     * @return string
653
     */
654
    private function exportTransactions(): string
655
    {
656
        // TODO better place for keys?
657
        $header    = ['user_id', 'group_id', 'journal_id', 'created_at', 'updated_at', 'group_title', 'type', 'amount', 'foreign_amount', 'currency_code',
658
                      'foreign_currency_code', 'description', 'date', 'source_name', 'source_iban', 'source_type', 'destination_name', 'destination_iban',
659
                      'destination_type', 'reconciled', 'category', 'budget', 'bill', 'tags',];
660
        $collector = app(GroupCollectorInterface::class);
661
        $collector->setUser($this->user);
662
        $collector->setRange($this->start, $this->end)->withAccountInformation()->withCategoryInformation()->withBillInformation()
663
                  ->withBudgetInformation()->withTagInformation();
664
        $journals = $collector->getExtractedJournals();
665
666
        $records = [];
667
        /** @var array $journal */
668
        foreach ($journals as $journal) {
669
            $records[] = [
670
                $journal['user_id'],
671
                $journal['transaction_group_id'],
672
                $journal['transaction_journal_id'],
673
                $journal['created_at']->toAtomString(),
674
                $journal['updated_at']->toAtomString(),
675
                $journal['transaction_group_title'],
676
                $journal['transaction_type_type'],
677
                $journal['amount'],
678
                $journal['foreign_amount'],
679
                $journal['currency_code'],
680
                $journal['foreign_currency_code'],
681
                $journal['description'],
682
                $journal['date']->toAtomString(),
683
                $journal['source_account_name'],
684
                $journal['source_account_iban'],
685
                $journal['source_account_type'],
686
                $journal['destination_account_name'],
687
                $journal['destination_account_iban'],
688
                $journal['destination_account_type'],
689
                $journal['reconciled'],
690
                $journal['category_name'],
691
                $journal['budget_name'],
692
                $journal['bill_name'],
693
                $this->mergeTags($journal['tags']),
694
            ];
695
696
        }
697
698
        //load the CSV document from a string
699
        $csv = Writer::createFromString('');
700
701
        //insert the header
702
        $csv->insertOne($header);
703
704
        //insert all the records
705
        $csv->insertAll($records);
706
707
        return $csv->getContent(); //returns the CSV document as a string
708
    }
709
710
    /**
711
     * @param array $tags
712
     *
713
     * @return string
714
     */
715
    private function mergeTags(array $tags): string
716
    {
717
        if (0 === count($tags)) {
718
            return '';
719
        }
720
        $smol = [];
721
        foreach ($tags as $tag) {
722
            $smol[] = $tag['name'];
723
        }
724
725
        return implode(',', $smol);
726
    }
727
728
}
729