MappingController::getFireflyIIIAccounts()   A
last analyzed

Complexity

Conditions 6
Paths 8

Size

Total Lines 24
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 16
c 1
b 0
f 0
dl 0
loc 24
rs 9.1111
cc 6
nc 8
nop 0
1
<?php
2
3
declare(strict_types=1);
4
/**
5
 * MappingController.php
6
 * Copyright (c) 2020 [email protected].
7
 *
8
 * This file is part of the Firefly III bunq importer
9
 * (https://github.com/firefly-iii/bunq-importer).
10
 *
11
 * This program is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU Affero General Public License as
13
 * published by the Free Software Foundation, either version 3 of the
14
 * License, or (at your option) any later version.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU Affero General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU Affero General Public License
22
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
23
 */
24
25
namespace App\Http\Controllers\Import;
26
27
use App\Http\Controllers\Controller;
28
use App\Services\Configuration\Configuration;
29
use App\Services\Session\Constants;
30
use GrumpyDictator\FFIIIApiSupport\Exceptions\ApiHttpException;
31
use GrumpyDictator\FFIIIApiSupport\Request\GetAccountsRequest;
32
use GrumpyDictator\FFIIIApiSupport\Response\GetAccountsResponse;
33
use Illuminate\Contracts\Filesystem\FileNotFoundException;
34
use Illuminate\Http\RedirectResponse;
35
use Illuminate\Http\Request;
36
use Illuminate\Support\Facades\Storage;
37
38
/**
39
 * Class MappingController.
40
 */
41
class MappingController extends Controller
42
{
43
    /**
44
     * MappingController constructor.
45
     */
46
    public function __construct()
47
    {
48
        parent::__construct();
49
        app('view')->share('pageTitle', 'Map your bunq data to Firefly III');
50
    }
51
52
    /**
53
     * @throws ApiHttpException
54
     */
55
    public function index()
56
    {
57
        $mainTitle = 'Map data';
58
        $subTitle  = 'Link bunq information to Firefly III data.';
59
60
        $configuration = Configuration::fromArray([]);
61
        if (session()->has(Constants::CONFIGURATION)) {
62
            $configuration = Configuration::fromArray(session()->get(Constants::CONFIGURATION));
63
        }
64
        // if config says to skip it, skip it:
65
        if (null !== $configuration && false === $configuration->isDoMapping()) {
66
            // skipForm
67
            return redirect()->route('import.sync.index');
68
        }
69
70
        $mapping = $configuration->getMapping();
71
72
        // parse all opposing accounts from the download
73
        $bunqAccounts = $this->getOpposingAccounts();
74
75
        // get accounts from Firefly III
76
        $ff3Accounts = $this->getFireflyIIIAccounts();
77
78
        return view('import.mapping.index', compact('mainTitle', 'subTitle', 'configuration', 'bunqAccounts', 'ff3Accounts', 'mapping'));
79
    }
80
81
    /**
82
     * @param Request $request
83
     *
84
     * @return RedirectResponse
85
     *
86
     * @psalm-return RedirectResponse|\Illuminate\Routing\Redirector
87
     */
88
    public function postIndex(Request $request)
89
    {
90
        // post mapping is not particularly complex.
91
        $result       = $request->all();
92
        $mapping      = $result['mapping'] ?? [];
93
        $accountTypes = $result['account_type'] ?? [];
94
95
        $configuration = Configuration::fromArray([]);
96
        if (session()->has(Constants::CONFIGURATION)) {
97
            $configuration = Configuration::fromArray(session()->get(Constants::CONFIGURATION));
98
        }
99
        // if config says to skip it, skip it:
100
        if (null !== $configuration && false === $configuration->isDoMapping()) {
101
            // skipForm
102
            return redirect()->route('import.sync.index');
103
        }
104
        // save mapping in config.
105
        $configuration->setMapping($mapping);
106
        $configuration->setAccountTypes($accountTypes);
107
108
        // save mapping in config, save config.
109
        session()->put(Constants::CONFIGURATION, $configuration->toArray());
110
111
        return redirect(route('import.sync.index'));
112
    }
113
114
    /**
115
     * @throws ApiHttpException
116
     * @return array
117
     */
118
    private function getFireflyIIIAccounts(): array
119
    {
120
        $token   = (string) config('bunq.access_token');
121
        $uri     = (string) config('bunq.uri');
122
        $request = new GetAccountsRequest($uri, $token);
123
        /** @var GetAccountsResponse $result */
124
        $result = $request->get();
125
        $return = [];
126
        foreach ($result as $entry) {
127
            $type = $entry->type;
128
            if ('reconciliation' === $type || 'initial-balance' === $type) {
129
                continue;
130
            }
131
            $id                 = (int) $entry->id;
132
            $return[$type][$id] = $entry->name;
133
            if ('' !== (string) $entry->iban) {
134
                $return[$type][$id] = sprintf('%s (%s)', $entry->name, $entry->iban);
135
            }
136
        }
137
        foreach ($return as $type => $entries) {
138
            asort($return[$type]);
139
        }
140
141
        return $return;
142
    }
143
144
    /**
145
     * @throws FileNotFoundException
146
     * @return array
147
     */
148
    private function getOpposingAccounts(): array
149
    {
150
        $downloadIdentifier = session()->get(Constants::DOWNLOAD_JOB_IDENTIFIER);
151
        $disk               = Storage::disk('downloads');
152
        $json               = $disk->get($downloadIdentifier);
153
        $array              = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
154
        $opposing           = [];
155
        /** @var array $account */
156
        foreach ($array as $account) {
157
            foreach ($account as $entry) {
158
                if ('' === trim((string) $entry['counter_party']['iban'])) {
159
                    $opposing[] = trim($entry['counter_party']['display_name']);
160
                }
161
                if ('' !== trim((string) $entry['counter_party']['iban'])) {
162
                    $opposing[] = sprintf('%s (%s)', trim($entry['counter_party']['display_name']), trim($entry['counter_party']['iban']));
163
                }
164
            }
165
        }
166
        $filtered = array_filter(
167
            $opposing,
168
            static function (string $value) {
169
                return '' !== $value;
170
            }
171
        );
172
173
        return array_unique($filtered);
174
    }
175
}
176