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.

Issues (724)

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

1
<?php
2
3
/**
4
 * AccountController.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
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\Api\V1\Requests\DateRequest;
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\Support\Http\Api\ApiSupport;
36
use FireflyIII\User;
37
use Illuminate\Http\JsonResponse;
38
39
/**
40
 * Class AccountController
41
 */
42
class AccountController extends Controller
43
{
44
    use ApiSupport;
45
    /** @var CurrencyRepositoryInterface */
46
    private $currencyRepository;
47
    /** @var AccountRepositoryInterface */
48
    private $repository;
49
50
    /**
51
     * AccountController constructor.
52
     *
53
     * @codeCoverageIgnore
54
     */
55
    public function __construct()
56
    {
57
        parent::__construct();
58
        $this->middleware(
59
            function ($request, $next) {
60
                /** @var User $user */
61
                $user             = auth()->user();
62
                $this->repository = app(AccountRepositoryInterface::class);
63
                $this->repository->setUser($user);
64
65
                $this->currencyRepository = app(CurrencyRepositoryInterface::class);
66
                $this->currencyRepository->setUser($user);
67
68
                return $next($request);
69
            }
70
        );
71
    }
72
73
    /**
74
     * @param DateRequest $request
75
     *
76
     * @return JsonResponse
77
     */
78
    public function expenseOverview(DateRequest $request): JsonResponse
79
    {
80
        // parameters for chart:
81
        $dates = $request->getAll();
82
        /** @var Carbon $start */
83
        $start = $dates['start'];
84
        /** @var Carbon $end */
85
        $end = $dates['end'];
86
87
        $start->subDay();
88
89
        // prep some vars:
90
        $currencies = [];
91
        $chartData  = [];
92
        $tempData   = [];
93
94
        // grab all accounts and names
95
        $accounts      = $this->repository->getAccountsByType([AccountType::EXPENSE]);
96
        $accountNames  = $this->extractNames($accounts);
97
        $startBalances = app('steam')->balancesPerCurrencyByAccounts($accounts, $start);
98
        $endBalances   = app('steam')->balancesPerCurrencyByAccounts($accounts, $end);
99
100
        // loop the end balances. This is an array for each account ($expenses)
101
        foreach ($endBalances as $accountId => $expenses) {
102
            $accountId = (int) $accountId;
103
            // loop each expense entry (each entry can be a different currency).
104
            foreach ($expenses as $currencyId => $endAmount) {
105
                $currencyId = (int) $currencyId;
106
107
                // see if there is an accompanying start amount.
108
                // grab the difference and find the currency.
109
                $startAmount             = $startBalances[$accountId][$currencyId] ?? '0';
110
                $diff                    = bcsub($endAmount, $startAmount);
111
                $currencies[$currencyId] = $currencies[$currencyId] ?? $this->currencyRepository->findNull($currencyId);
112
                if (0 !== bccomp($diff, '0')) {
113
                    // store the values in a temporary array.
114
                    $tempData[] = [
115
                        'name'        => $accountNames[$accountId],
116
                        'difference'  => $diff,
117
                        'diff_float'  => (float) $diff,
118
                        'currency_id' => $currencyId,
119
                    ];
120
                }
121
            }
122
        }
123
124
        // sort temp array by amount.
125
        $amounts = array_column($tempData, 'diff_float');
126
        array_multisort($amounts, SORT_DESC, $tempData);
127
128
        // loop all found currencies and build the data array for the chart.
129
        /**
130
         * @var int                 $currencyId
131
         * @var TransactionCurrency $currency
132
         */
133
        foreach ($currencies as $currencyId => $currency) {
134
            $currentSet             = [
135
                'label'                   => trans('firefly.box_spent_in_currency', ['currency' => $currency->symbol]),
136
                'currency_id'             => $currency->id,
137
                'currency_code'           => $currency->code,
138
                'currency_symbol'         => $currency->symbol,
139
                'currency_decimal_places' => $currency->decimal_places,
140
                'type'                    => 'bar', // line, area or bar
141
                'yAxisID'                 => 0, // 0, 1, 2
142
                'entries'                 => $this->expandNames($tempData),
143
            ];
144
            $chartData[$currencyId] = $currentSet;
145
        }
146
147
        // loop temp data and place data in correct array:
148
        foreach ($tempData as $entry) {
149
            $currencyId                               = $entry['currency_id'];
150
            $name                                     = $entry['name'];
151
            $chartData[$currencyId]['entries'][$name] = round($entry['difference'], $chartData[$currencyId]['currency_decimal_places']);
152
        }
153
        $chartData = array_values($chartData);
154
155
        return response()->json($chartData);
156
    }
157
158
159
    /**
160
     * @param DateRequest $request
161
     *
162
     * @return JsonResponse
163
     */
164
    public function overview(DateRequest $request): JsonResponse
165
    {
166
        // parameters for chart:
167
        $dates = $request->getAll();
168
        /** @var Carbon $start */
169
        $start = $dates['start'];
170
        /** @var Carbon $end */
171
        $end = $dates['end'];
172
173
        // user's preferences
174
        $defaultSet = $this->repository->getAccountsByType([AccountType::ASSET])->pluck('id')->toArray();
175
        $frontPage  = app('preferences')->get('frontPageAccounts', $defaultSet);
176
        $default    = app('amount')->getDefaultCurrency();
177
        // @codeCoverageIgnoreStart
178
        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

178
        if (0 === count(/** @scrutinizer ignore-type */ $frontPage->data)) {
Loading history...
179
            $frontPage->data = $defaultSet;
180
            $frontPage->save();
181
        }
182
        // @codeCoverageIgnoreEnd
183
184
        // get accounts:
185
        $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

185
        $accounts  = $this->repository->getAccountsById(/** @scrutinizer ignore-type */ $frontPage->data);
Loading history...
186
        $chartData = [];
187
        /** @var Account $account */
188
        foreach ($accounts as $account) {
189
            $currency = $this->repository->getAccountCurrency($account);
190
            if (null === $currency) {
191
                $currency = $default; // @codeCoverageIgnore
192
            }
193
            $currentSet = [
194
                'label'                   => $account->name,
195
                'currency_id'             => $currency->id,
196
                'currency_code'           => $currency->code,
197
                'currency_symbol'         => $currency->symbol,
198
                'currency_decimal_places' => $currency->decimal_places,
199
                'type'                    => 'line', // line, area or bar
200
                'yAxisID'                 => 0, // 0, 1, 2
201
                'entries'                 => [],
202
            ];
203
            /** @var Carbon $currentStart */
204
            $currentStart = clone $start;
205
            $range        = app('steam')->balanceInRange($account, $start, clone $end);
206
            $previous     = round(array_values($range)[0], 12);
207
            while ($currentStart <= $end) {
208
                $format   = $currentStart->format('Y-m-d');
209
                $label    = $currentStart->format('Y-m-d');
210
                $balance  = isset($range[$format]) ? round($range[$format], 12) : $previous;
211
                $previous = $balance;
212
                $currentStart->addDay();
213
                $currentSet['entries'][$label] = $balance;
214
            }
215
            $chartData[] = $currentSet;
216
        }
217
218
        return response()->json($chartData);
219
    }
220
221
    /**
222
     * @param DateRequest $request
223
     *
224
     * @return JsonResponse
225
     */
226
    public function revenueOverview(DateRequest $request): JsonResponse
227
    {
228
        // parameters for chart:
229
        $dates = $request->getAll();
230
        /** @var Carbon $start */
231
        $start = $dates['start'];
232
        /** @var Carbon $end */
233
        $end = $dates['end'];
234
235
        $start->subDay();
236
237
        // prep some vars:
238
        $currencies = [];
239
        $chartData  = [];
240
        $tempData   = [];
241
242
        // grab all accounts and names
243
        $accounts      = $this->repository->getAccountsByType([AccountType::REVENUE]);
244
        $accountNames  = $this->extractNames($accounts);
245
        $startBalances = app('steam')->balancesPerCurrencyByAccounts($accounts, $start);
246
        $endBalances   = app('steam')->balancesPerCurrencyByAccounts($accounts, $end);
247
248
        // loop the end balances. This is an array for each account ($expenses)
249
        foreach ($endBalances as $accountId => $expenses) {
250
            $accountId = (int) $accountId;
251
            // loop each expense entry (each entry can be a different currency).
252
            foreach ($expenses as $currencyId => $endAmount) {
253
                $currencyId = (int) $currencyId;
254
255
                // see if there is an accompanying start amount.
256
                // grab the difference and find the currency.
257
                $startAmount             = $startBalances[$accountId][$currencyId] ?? '0';
258
                $diff                    = bcsub($endAmount, $startAmount);
259
                $currencies[$currencyId] = $currencies[$currencyId] ?? $this->currencyRepository->findNull($currencyId);
260
                if (0 !== bccomp($diff, '0')) {
261
                    // store the values in a temporary array.
262
                    $tempData[] = [
263
                        'name'        => $accountNames[$accountId],
264
                        'difference'  => bcmul($diff, '-1'),
265
                        //  For some reason this line is never covered in code coverage:
266
                        'diff_float'  => ((float) $diff) * -1, // @codeCoverageIgnore
267
                        'currency_id' => $currencyId,
268
                    ];
269
                }
270
            }
271
        }
272
273
        // sort temp array by amount.
274
        $amounts = array_column($tempData, 'diff_float');
275
        array_multisort($amounts, SORT_DESC, $tempData);
276
277
        // loop all found currencies and build the data array for the chart.
278
        /**
279
         * @var int                 $currencyId
280
         * @var TransactionCurrency $currency
281
         */
282
        foreach ($currencies as $currencyId => $currency) {
283
            $currentSet             = [
284
                'label'                   => trans('firefly.box_earned_in_currency', ['currency' => $currency->symbol]),
285
                'currency_id'             => $currency->id,
286
                'currency_code'           => $currency->code,
287
                'currency_symbol'         => $currency->symbol,
288
                'currency_decimal_places' => $currency->decimal_places,
289
                'type'                    => 'bar', // line, area or bar
290
                'yAxisID'                 => 0, // 0, 1, 2
291
                'entries'                 => $this->expandNames($tempData),
292
            ];
293
            $chartData[$currencyId] = $currentSet;
294
        }
295
296
        // loop temp data and place data in correct array:
297
        foreach ($tempData as $entry) {
298
            $currencyId                               = $entry['currency_id'];
299
            $name                                     = $entry['name'];
300
            $chartData[$currencyId]['entries'][$name] = round($entry['difference'], $chartData[$currencyId]['currency_decimal_places']);
301
        }
302
        $chartData = array_values($chartData);
303
304
        return response()->json($chartData);
305
    }
306
307
}
308