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 ( cf47da...53c71b )
by James
21:48 queued 09:49
created

app/Api/V1/Controllers/Chart/AccountController.php (2 issues)

Labels
Severity
1
<?php
2
3
/**
4
 * AccountController.php
5
 * Copyright (c) 2019 [email protected]
6
 *
7
 * This file is part of Firefly III.
8
 *
9
 * Firefly III is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation, either version 3 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * Firefly III 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 General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
21
 */
22
23
declare(strict_types=1);
24
25
namespace FireflyIII\Api\V1\Controllers\Chart;
26
27
use Carbon\Carbon;
28
use FireflyIII\Api\V1\Controllers\Controller;
29
use FireflyIII\Exceptions\FireflyException;
30
use FireflyIII\Models\Account;
31
use FireflyIII\Models\AccountType;
32
use FireflyIII\Models\TransactionCurrency;
33
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
34
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
35
use FireflyIII\User;
36
use Illuminate\Http\JsonResponse;
37
use Illuminate\Http\Request;
38
use Illuminate\Support\Collection;
39
40
/**
41
 * Class AccountController
42
 */
43
class AccountController extends Controller
44
{
45
    /** @var CurrencyRepositoryInterface */
46
    private $currencyRepository;
47
    /** @var AccountRepositoryInterface */
48
    private $repository;
49
50
    /**
51
     * AccountController constructor.
52
     */
53
    public function __construct()
54
    {
55
        parent::__construct();
56
        $this->middleware(
57
            function ($request, $next) {
58
                /** @var User $user */
59
                $user             = auth()->user();
60
                $this->repository = app(AccountRepositoryInterface::class);
61
                $this->repository->setUser($user);
62
63
                $this->currencyRepository = app(CurrencyRepositoryInterface::class);
64
                $this->currencyRepository->setUser($user);
65
66
                return $next($request);
67
            }
68
        );
69
    }
70
71
    /**
72
     * @param Request $request
73
     *
74
     * @return JsonResponse
75
     * @throws FireflyException
76
     */
77
    public function expenseOverview(Request $request): JsonResponse
78
    {
79
        // parameters for chart:
80
        $start = (string)$request->get('start');
81
        $end   = (string)$request->get('end');
82
        if ('' === $start || '' === $end) {
83
            throw new FireflyException('Start and end are mandatory parameters.');
84
        }
85
86
        $start = Carbon::createFromFormat('Y-m-d', $start);
87
        $end   = Carbon::createFromFormat('Y-m-d', $end);
88
        $start->subDay();
89
90
        // prep some vars:
91
        $currencies = [];
92
        $chartData  = [];
93
        $tempData   = [];
94
95
        // grab all accounts and names
96
        $accounts      = $this->repository->getAccountsByType([AccountType::EXPENSE]);
97
        $accountNames  = $this->extractNames($accounts);
98
        $startBalances = app('steam')->balancesPerCurrencyByAccounts($accounts, $start);
99
        $endBalances   = app('steam')->balancesPerCurrencyByAccounts($accounts, $end);
100
101
        // loop the end balances. This is an array for each account ($expenses)
102
        foreach ($endBalances as $accountId => $expenses) {
103
            $accountId = (int)$accountId;
104
            // loop each expense entry (each entry can be a different currency).
105
            foreach ($expenses as $currencyId => $endAmount) {
106
                $currencyId = (int)$currencyId;
107
108
                // see if there is an accompanying start amount.
109
                // grab the difference and find the currency.
110
                $startAmount             = $startBalances[$accountId][$currencyId] ?? '0';
111
                $diff                    = bcsub($endAmount, $startAmount);
112
                $currencies[$currencyId] = $currencies[$currencyId] ?? $this->currencyRepository->findNull($currencyId);
113
                if (0 !== bccomp($diff, '0')) {
114
                    // store the values in a temporary array.
115
                    $tempData[] = [
116
                        'name'        => $accountNames[$accountId],
117
                        'difference'  => $diff,
118
                        'diff_float'  => (float)$diff,
119
                        'currency_id' => $currencyId,
120
                    ];
121
                }
122
            }
123
        }
124
125
        // sort temp array by amount.
126
        $amounts = array_column($tempData, 'diff_float');
127
        array_multisort($amounts, SORT_DESC, $tempData);
128
129
        // loop all found currencies and build the data array for the chart.
130
        /**
131
         * @var int                 $currencyId
132
         * @var TransactionCurrency $currency
133
         */
134
        foreach ($currencies as $currencyId => $currency) {
135
            $currentSet             = [
136
                'label'                   => trans('firefly.box_spent_in_currency', ['currency' => $currency->symbol]),
137
                'currency_id'             => $currency->id,
138
                'currency_code'           => $currency->code,
139
                'currency_symbol'         => $currency->symbol,
140
                'currency_decimal_places' => $currency->decimal_places,
141
                'type'                    => 'bar', // line, area or bar
142
                'yAxisID'                 => 0, // 0, 1, 2
143
                'entries'                 => $this->expandNames($tempData),
144
            ];
145
            $chartData[$currencyId] = $currentSet;
146
        }
147
148
        // loop temp data and place data in correct array:
149
        foreach ($tempData as $entry) {
150
            $currencyId                               = $entry['currency_id'];
151
            $name                                     = $entry['name'];
152
            $chartData[$currencyId]['entries'][$name] = round($entry['difference'], $chartData[$currencyId]['currency_decimal_places']);
153
        }
154
        $chartData = array_values($chartData);
155
156
        return response()->json($chartData);
157
    }
158
159
    /**
160
     * @param Request $request
161
     *
162
     * @return JsonResponse
163
     * @throws FireflyException
164
     */
165
    public function revenueOverview(Request $request): JsonResponse
166
    {
167
        // parameters for chart:
168
        $start = (string)$request->get('start');
169
        $end   = (string)$request->get('end');
170
        if ('' === $start || '' === $end) {
171
            throw new FireflyException('Start and end are mandatory parameters.');
172
        }
173
174
        $start = Carbon::createFromFormat('Y-m-d', $start);
175
        $end   = Carbon::createFromFormat('Y-m-d', $end);
176
        $start->subDay();
177
178
        // prep some vars:
179
        $currencies = [];
180
        $chartData  = [];
181
        $tempData   = [];
182
183
        // grab all accounts and names
184
        $accounts      = $this->repository->getAccountsByType([AccountType::REVENUE]);
185
        $accountNames  = $this->extractNames($accounts);
186
        $startBalances = app('steam')->balancesPerCurrencyByAccounts($accounts, $start);
187
        $endBalances   = app('steam')->balancesPerCurrencyByAccounts($accounts, $end);
188
189
        // loop the end balances. This is an array for each account ($expenses)
190
        foreach ($endBalances as $accountId => $expenses) {
191
            $accountId = (int)$accountId;
192
            // loop each expense entry (each entry can be a different currency).
193
            foreach ($expenses as $currencyId => $endAmount) {
194
                $currencyId = (int)$currencyId;
195
196
                // see if there is an accompanying start amount.
197
                // grab the difference and find the currency.
198
                $startAmount             = $startBalances[$accountId][$currencyId] ?? '0';
199
                $diff                    = bcsub($endAmount, $startAmount);
200
                $currencies[$currencyId] = $currencies[$currencyId] ?? $this->currencyRepository->findNull($currencyId);
201
                if (0 !== bccomp($diff, '0')) {
202
                    // store the values in a temporary array.
203
                    $tempData[] = [
204
                        'name'        => $accountNames[$accountId],
205
                        'difference'  => bcmul($diff,'-1'),
206
                        'diff_float'  => (float)$diff * -1,
207
                        'currency_id' => $currencyId,
208
                    ];
209
                }
210
            }
211
        }
212
213
        // sort temp array by amount.
214
        $amounts = array_column($tempData, 'diff_float');
215
        array_multisort($amounts, SORT_DESC, $tempData);
216
217
        // loop all found currencies and build the data array for the chart.
218
        /**
219
         * @var int                 $currencyId
220
         * @var TransactionCurrency $currency
221
         */
222
        foreach ($currencies as $currencyId => $currency) {
223
            $currentSet             = [
224
                'label'                   => trans('firefly.box_earned_in_currency', ['currency' => $currency->symbol]),
225
                'currency_id'             => $currency->id,
226
                'currency_code'           => $currency->code,
227
                'currency_symbol'         => $currency->symbol,
228
                'currency_decimal_places' => $currency->decimal_places,
229
                'type'                    => 'bar', // line, area or bar
230
                'yAxisID'                 => 0, // 0, 1, 2
231
                'entries'                 => $this->expandNames($tempData),
232
            ];
233
            $chartData[$currencyId] = $currentSet;
234
        }
235
236
        // loop temp data and place data in correct array:
237
        foreach ($tempData as $entry) {
238
            $currencyId                               = $entry['currency_id'];
239
            $name                                     = $entry['name'];
240
            $chartData[$currencyId]['entries'][$name] = round($entry['difference'], $chartData[$currencyId]['currency_decimal_places']);
241
        }
242
        $chartData = array_values($chartData);
243
244
        return response()->json($chartData);
245
    }
246
247
    /**
248
     * @param Request $request
249
     *
250
     * @return JsonResponse
251
     * @throws FireflyException
252
     */
253
    public function overview(Request $request): JsonResponse
254
    {
255
        // parameters for chart:
256
        $start = (string)$request->get('start');
257
        $end   = (string)$request->get('end');
258
        if ('' === $start || '' === $end) {
259
            throw new FireflyException('Start and end are mandatory parameters.');
260
        }
261
262
        $start = Carbon::createFromFormat('Y-m-d', $start);
263
        $end   = Carbon::createFromFormat('Y-m-d', $end);
264
265
        // user's preferences
266
        $defaultSet = $this->repository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET])->pluck('id')->toArray();
267
        $frontPage  = app('preferences')->get('frontPageAccounts', $defaultSet);
268
        $default    = app('amount')->getDefaultCurrency();
269
        if (0 === \count($frontPage->data)) {
0 ignored issues
show
$frontPage->data of type string is incompatible with the type Countable|array expected by parameter $var of count(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

269
        if (0 === \count(/** @scrutinizer ignore-type */ $frontPage->data)) {
Loading history...
270
            $frontPage->data = $defaultSet;
271
            $frontPage->save();
272
        }
273
274
        // get accounts:
275
        $accounts  = $this->repository->getAccountsById($frontPage->data);
0 ignored issues
show
$frontPage->data of type string is incompatible with the type array expected by parameter $accountIds of FireflyIII\Repositories\...face::getAccountsById(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

275
        $accounts  = $this->repository->getAccountsById(/** @scrutinizer ignore-type */ $frontPage->data);
Loading history...
276
        $chartData = [];
277
        /** @var Account $account */
278
        foreach ($accounts as $account) {
279
            $currency = $this->repository->getAccountCurrency($account);
280
            if (null === $currency) {
281
                $currency = $default;
282
            }
283
            $currentSet = [
284
                'label'                   => $account->name,
285
                'currency_id'             => $currency->id,
286
                'currency_code'           => $currency->code,
287
                'currency_symbol'         => $currency->symbol,
288
                'currency_decimal_places' => $currency->decimal_places,
289
                'type'                    => 'line', // line, area or bar
290
                'yAxisID'                 => 0, // 0, 1, 2
291
                'entries'                 => [],
292
            ];
293
294
            $currentStart = clone $start;
295
            $range        = app('steam')->balanceInRange($account, $start, clone $end);
296
            $previous     = round(array_values($range)[0], 12);
297
            while ($currentStart <= $end) {
298
                $format   = $currentStart->format('Y-m-d');
299
                $label    = $currentStart->format('Y-m-d');
300
                $balance  = isset($range[$format]) ? round($range[$format], 12) : $previous;
301
                $previous = $balance;
302
                $currentStart->addDay();
303
                $currentSet['entries'][$label] = $balance;
304
            }
305
            $chartData[] = $currentSet;
306
        }
307
308
        return response()->json($chartData);
309
    }
310
311
    /**
312
     * Small helper function for the revenue and expense account charts.
313
     * TODO should include Trait instead of doing this.
314
     *
315
     * @param array $names
316
     *
317
     * @return array
318
     */
319
    protected function expandNames(array $names): array
320
    {
321
        $result = [];
322
        foreach ($names as $entry) {
323
            $result[$entry['name']] = 0;
324
        }
325
326
        return $result;
327
    }
328
329
    /**
330
     * Small helper function for the revenue and expense account charts.
331
     * TODO should include Trait instead of doing this.
332
     *
333
     * @param Collection $accounts
334
     *
335
     * @return array
336
     */
337
    protected function extractNames(Collection $accounts): array
338
    {
339
        $return = [];
340
        /** @var Account $account */
341
        foreach ($accounts as $account) {
342
            $return[$account->id] = $account->name;
343
        }
344
345
        return $return;
346
    }
347
348
}
349