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 ( 49de82...9f1fc0 )
by James
35:45 queued 23:44
created

TransactionUpdateRequest::getAll()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 76
Code Lines 59

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 59
dl 0
loc 76
rs 8.8945
c 0
b 0
f 0
cc 2
nc 2
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * TransactionUpdateRequest.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\Requests;
26
27
use FireflyIII\Models\TransactionGroup;
28
use FireflyIII\Rules\BelongsUser;
29
use FireflyIII\Rules\IsBoolean;
30
use FireflyIII\Rules\IsDateOrTime;
31
use FireflyIII\Validation\TransactionValidation;
32
use Illuminate\Validation\Validator;
33
use Log;
34
35
/**
36
 * Class TransactionUpdateRequest
37
 */
38
class TransactionUpdateRequest extends Request
39
{
40
    use TransactionValidation;
0 ignored issues
show
introduced by
The trait FireflyIII\Validation\TransactionValidation requires some properties which are not provided by FireflyIII\Api\V1\Reques...ransactionUpdateRequest: $name, $sourceError, $destError, $transactionType, $account_id, $account, $type
Loading history...
41
42
    /** @var array Array values. */
43
    private $arrayFields;
44
    /** @var array Boolean values. */
45
    private $booleanFields;
46
    /** @var array Fields that contain date values. */
47
    private $dateFields;
48
    /** @var array Fields that contain integer values. */
49
    private $integerFields;
50
    /** @var array Fields that contain string values. */
51
    private $stringFields;
52
    /** @var array Fields that contain text (with newlines) */
53
    private $textareaFields;
54
55
    /**
56
     * Authorize logged in users.
57
     *
58
     * @return bool
59
     */
60
    public function authorize(): bool
61
    {
62
        // Only allow authenticated users
63
        return auth()->check();
64
    }
65
66
    /**
67
     * Get all data. Is pretty complex because of all the ??-statements.
68
     *
69
     * @return array
70
     */
71
    public function getAll(): array
72
    {
73
        $this->integerFields = [
74
            'order',
75
            'currency_id',
76
            'foreign_currency_id',
77
            'transaction_journal_id',
78
            'source_id',
79
            'destination_id',
80
            'budget_id',
81
            'category_id',
82
            'bill_id',
83
            'recurrence_id',
84
        ];
85
86
        $this->dateFields = [
87
            'date',
88
            'interest_date',
89
            'book_date',
90
            'process_date',
91
            'due_date',
92
            'payment_date',
93
            'invoice_date',
94
        ];
95
96
        $this->textareaFields = [
97
            'notes',
98
        ];
99
100
        $this->stringFields  = [
101
            'type',
102
            'currency_code',
103
            'foreign_currency_code',
104
            'amount',
105
            'foreign_amount',
106
            'description',
107
            'source_name',
108
            'source_iban',
109
            'source_number',
110
            'source_bic',
111
            'destination_name',
112
            'destination_iban',
113
            'destination_number',
114
            'destination_bic',
115
            'budget_name',
116
            'category_name',
117
            'bill_name',
118
            'internal_reference',
119
            'external_id',
120
            'bunq_payment_id',
121
            'sepa_cc',
122
            'sepa_ct_op',
123
            'sepa_ct_id',
124
            'sepa_db',
125
            'sepa_country',
126
            'sepa_ep',
127
            'sepa_ci',
128
            'sepa_batch_id',
129
        ];
130
        $this->booleanFields = [
131
            'reconciled',
132
        ];
133
134
        $this->arrayFields = [
135
            'tags',
136
        ];
137
138
139
        $data = [
140
            'transactions' => $this->getTransactionData(),
141
        ];
142
        if ($this->has('group_title')) {
143
            $data['group_title'] = $this->string('group_title');
144
        }
145
146
        return $data;
147
    }
148
149
    /**
150
     * The rules that the incoming request must be matched against.
151
     *
152
     * @return array
153
     */
154
    public function rules(): array
155
    {
156
        $rules = [
157
            // basic fields for group:
158
            'group_title'                          => 'between:1,1000',
159
160
            // transaction rules (in array for splits):
161
            'transactions.*.type'                  => 'in:withdrawal,deposit,transfer,opening-balance,reconciliation',
162
            'transactions.*.date'                  => [new IsDateOrTime],
163
            'transactions.*.order'                 => 'numeric|min:0',
164
165
            // currency info
166
            'transactions.*.currency_id'           => 'numeric|exists:transaction_currencies,id',
167
            'transactions.*.currency_code'         => 'min:3|max:3|exists:transaction_currencies,code',
168
            'transactions.*.foreign_currency_id'   => 'numeric|exists:transaction_currencies,id',
169
            'transactions.*.foreign_currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
170
171
            // amount
172
            'transactions.*.amount'                => 'numeric|more:0|max:100000000000',
173
            'transactions.*.foreign_amount'        => 'numeric|gte:0',
174
175
            // description
176
            'transactions.*.description'           => 'nullable|between:1,1000',
177
178
            // source of transaction
179
            'transactions.*.source_id'             => ['numeric', 'nullable', new BelongsUser],
180
            'transactions.*.source_name'           => 'between:1,255|nullable',
181
182
            // destination of transaction
183
            'transactions.*.destination_id'        => ['numeric', 'nullable', new BelongsUser],
184
            'transactions.*.destination_name'      => 'between:1,255|nullable',
185
186
            // budget, category, bill and piggy
187
            'transactions.*.budget_id'             => ['mustExist:budgets,id', new BelongsUser],
188
            'transactions.*.budget_name'           => ['between:1,255', 'nullable', new BelongsUser],
189
            'transactions.*.category_id'           => ['mustExist:categories,id', new BelongsUser],
190
            'transactions.*.category_name'         => 'between:1,255|nullable',
191
            'transactions.*.bill_id'               => ['numeric', 'nullable', 'mustExist:bills,id', new BelongsUser],
192
            'transactions.*.bill_name'             => ['between:1,255', 'nullable', new BelongsUser],
193
194
            // other interesting fields
195
            'transactions.*.reconciled'            => [new IsBoolean],
196
            'transactions.*.notes'                 => 'min:1,max:50000|nullable',
197
            'transactions.*.tags'                  => 'between:0,255',
198
199
            // meta info fields
200
            'transactions.*.internal_reference'    => 'min:1,max:255|nullable',
201
            'transactions.*.external_id'           => 'min:1,max:255|nullable',
202
            'transactions.*.recurrence_id'         => 'min:1,max:255|nullable',
203
            'transactions.*.bunq_payment_id'       => 'min:1,max:255|nullable',
204
205
            // SEPA fields:
206
            'transactions.*.sepa_cc'               => 'min:1,max:255|nullable',
207
            'transactions.*.sepa_ct_op'            => 'min:1,max:255|nullable',
208
            'transactions.*.sepa_ct_id'            => 'min:1,max:255|nullable',
209
            'transactions.*.sepa_db'               => 'min:1,max:255|nullable',
210
            'transactions.*.sepa_country'          => 'min:1,max:255|nullable',
211
            'transactions.*.sepa_ep'               => 'min:1,max:255|nullable',
212
            'transactions.*.sepa_ci'               => 'min:1,max:255|nullable',
213
            'transactions.*.sepa_batch_id'         => 'min:1,max:255|nullable',
214
215
            // dates
216
            'transactions.*.interest_date'         => 'date|nullable',
217
            'transactions.*.book_date'             => 'date|nullable',
218
            'transactions.*.process_date'          => 'date|nullable',
219
            'transactions.*.due_date'              => 'date|nullable',
220
            'transactions.*.payment_date'          => 'date|nullable',
221
            'transactions.*.invoice_date'          => 'date|nullable',
222
        ];
223
224
        return $rules;
225
    }
226
227
    /**
228
     * Configure the validator instance.
229
     *
230
     * @param Validator $validator
231
     *
232
     * @return void
233
     */
234
    public function withValidator(Validator $validator): void
235
    {
236
        /** @var TransactionGroup $transactionGroup */
237
        $transactionGroup = $this->route()->parameter('transactionGroup');
238
        $validator->after(
239
            function (Validator $validator) use ($transactionGroup) {
240
                // must submit at least one transaction.
241
                $this->validateOneTransaction($validator);
242
243
                // if more than one, verify that there are journal ID's present.
244
                $this->validateJournalIds($validator, $transactionGroup);
245
246
                // all transaction types must be equal:
247
                $this->validateTransactionTypesForUpdate($validator);
248
249
                // validate source/destination is equal, depending on the transaction journal type.
250
                $this->validateEqualAccountsForUpdate($validator, $transactionGroup);
251
252
                // If type is set, source + destination info is mandatory.
253
                // Not going to do this. Not sure where the demand came from.
254
255
                // validate that the currency fits the source and/or destination account.
256
                // validate all account info
257
                $this->validateAccountInformationUpdate($validator);
258
259
                // The currency info must match the accounts involved.
260
                // Instead will ignore currency info as much as possible.
261
262
                // TODO if the transaction_journal_id is empty, some fields are mandatory, like the amount!
263
264
                // all journals must have a description
265
                //$this->validateDescriptions($validator);
266
267
                //                // validate foreign currency info
268
                //                $this->validateForeignCurrencyInformation($validator);
269
                //
270
271
                //
272
                //                // make sure all splits have valid source + dest info
273
                //                $this->validateSplitAccounts($validator);
274
                //                 the group must have a description if > 1 journal.
275
                //                $this->validateGroupDescription($validator);
276
            }
277
        );
278
    }
279
280
    /**
281
     * Get transaction data.
282
     *
283
     * @return array
284
     */
285
    private function getTransactionData(): array
286
    {
287
        Log::debug('Now in getTransactionData()');
288
        $return = [];
289
        /**
290
         * @var int   $index
291
         * @var array $transaction
292
         */
293
        foreach ($this->get('transactions') as $index => $transaction) {
294
            // default response is to update nothing in the transaction:
295
            $current = [];
296
297
            // for each field, add it to the array if a reference is present in the request:
298
            foreach ($this->integerFields as $fieldName) {
299
                if (array_key_exists($fieldName, $transaction)) {
300
                    $current[$fieldName] = $this->integerFromValue((string)$transaction[$fieldName]);
301
                }
302
            }
303
304
            foreach ($this->stringFields as $fieldName) {
305
                if (array_key_exists($fieldName, $transaction)) {
306
                    $current[$fieldName] = $this->stringFromValue((string)$transaction[$fieldName]);
307
                }
308
            }
309
310
            foreach ($this->textareaFields as $fieldName) {
311
                if (array_key_exists($fieldName, $transaction)) {
312
                    $current[$fieldName] = $this->nlStringFromValue((string)$transaction[$fieldName]);
313
                }
314
            }
315
316
            foreach ($this->dateFields as $fieldName) {
317
                Log::debug(sprintf('Now at date field %s', $fieldName));
318
                if (array_key_exists($fieldName, $transaction)) {
319
                    $current[$fieldName] = $this->dateFromValue((string)$transaction[$fieldName]);
320
                    Log::debug(sprintf('New value: "%s"', (string)$transaction[$fieldName]));
321
                }
322
            }
323
324
            foreach ($this->booleanFields as $fieldName) {
325
                if (array_key_exists($fieldName, $transaction)) {
326
                    $current[$fieldName] = $this->convertBoolean((string)$transaction[$fieldName]);
327
                }
328
            }
329
330
            foreach ($this->arrayFields as $fieldName) {
331
                if (array_key_exists($fieldName, $transaction)) {
332
                    $current[$fieldName] = $this->arrayFromValue($transaction[$fieldName]);
333
                }
334
            }
335
            $return[] = $current;
336
        }
337
338
        return $return;
339
    }
340
}
341