Passed
Branch develop (01f96b)
by
unknown
30:45
created

BankAccounts::addLine()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 26
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 18
c 0
b 0
f 0
nc 4
nop 9
dl 0
loc 26
rs 9.6666

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/*
3
 * Copyright (C) 2016 Xebax Christy <[email protected]>
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17
 */
18
19
use Luracast\Restler\RestException;
20
21
require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
22
23
/**
24
 * API class for accounts
25
 *
26
 * @property DoliDB db
27
 * @access protected
28
 * @class DolibarrApiAccess {@requires user,external}
29
 */
30
class BankAccounts extends DolibarrApi
31
{
32
33
    /**
34
     * array $FIELDS Mandatory fields, checked when creating an object
35
     */
36
    static $FIELDS = array(
37
        'ref',
38
        'label',
39
        'type',
40
        'currency_code',
41
        'country_id'
42
    );
43
44
    /**
45
     * Constructor
46
     */
47
    public function __construct()
48
    {
49
        global $db;
50
        $this->db = $db;
51
    }
52
53
    /**
54
     * Get the list of accounts.
55
     *
56
     * @param string    $sortfield  Sort field
57
     * @param string    $sortorder  Sort order
58
     * @param int       $limit      Limit for list
59
     * @param int       $page       Page number
60
	 * @param  int    	$category   Use this param to filter list by category
61
     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.import_key:<:'20160101')"
62
     * @return array                List of account objects
63
     *
64
     * @throws RestException
65
     */
66
    public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $category = 0, $sqlfilters = '')
67
    {
68
        $list = array();
69
70
        if (!DolibarrApiAccess::$user->rights->banque->lire) {
71
            throw new RestException(401);
72
        }
73
74
        $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."bank_account as t";
75
    	if ($category > 0) {
76
        $sql .= ", ".MAIN_DB_PREFIX."categorie_account as c";
77
		}
78
        $sql .= ' WHERE t.entity IN ('.getEntity('bank_account').')';
79
    	// Select accounts of given category
80
    	if ($category > 0) {
81
        $sql .= " AND c.fk_categorie = ".$db->escape($category)." AND c.fk_account = t.rowid ";
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $db seems to be never defined.
Loading history...
82
		}
83
        // Add sql filters
84
        if ($sqlfilters)
85
        {
86
            if (!DolibarrApi::_checkFilters($sqlfilters))
87
            {
88
                throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
89
            }
90
            $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
91
            $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
92
        }
93
94
        $sql .= $this->db->order($sortfield, $sortorder);
95
        if ($limit) {
96
            if ($page < 0)
97
            {
98
                $page = 0;
99
            }
100
            $offset = $limit * $page;
101
102
            $sql .= $this->db->plimit($limit + 1, $offset);
103
        }
104
105
        dol_syslog("API Rest request");
106
        $result = $this->db->query($sql);
107
108
        if ($result) {
109
            $num = $this->db->num_rows($result);
110
            $min = min($num, ($limit <= 0 ? $num : $limit));
111
            for ($i = 0; $i < $min; $i++) {
112
                $obj = $this->db->fetch_object($result);
113
                $account = new Account($this->db);
114
                if ($account->fetch($obj->rowid) > 0) {
115
                    $list[] = $this->_cleanObjectDatas($account);
116
                }
117
            }
118
        } else {
119
            throw new RestException(503, 'Error when retrieving list of accounts: '.$this->db->lasterror());
120
        }
121
122
        return $list;
123
    }
124
125
    /**
126
     * Get account by ID.
127
     *
128
     * @param int    $id    ID of account
129
     * @return array Account object
130
     *
131
     * @throws RestException
132
     */
133
    public function get($id)
134
    {
135
        if (!DolibarrApiAccess::$user->rights->banque->lire) {
136
            throw new RestException(401);
137
        }
138
139
        $account = new Account($this->db);
140
        $result = $account->fetch($id);
141
        if (!$result) {
142
            throw new RestException(404, 'account not found');
143
        }
144
145
        return $this->_cleanObjectDatas($account);
146
    }
147
148
    /**
149
     * Create account object
150
     *
151
     * @param array $request_data    Request data
152
     * @return int ID of account
153
     */
154
    public function post($request_data = null)
155
    {
156
        if (!DolibarrApiAccess::$user->rights->banque->configurer) {
157
            throw new RestException(401);
158
        }
159
        // Check mandatory fields
160
        $result = $this->_validate($request_data);
161
162
        $account = new Account($this->db);
163
        foreach ($request_data as $field => $value) {
164
            $account->$field = $value;
165
        }
166
        // Date of the initial balance (required to create an account).
167
        $account->date_solde = time();
168
        // courant and type are the same thing but the one used when
169
        // creating an account is courant
170
        $account->courant = $account->type;
171
172
        if ($account->create(DolibarrApiAccess::$user) < 0) {
173
            throw new RestException(500, 'Error creating bank account', array_merge(array($account->error), $account->errors));
174
        }
175
        return $account->id;
176
    }
177
178
    /**
179
     * Create an internal wire transfer between two bank accounts
180
     *
181
     * @param int     $bankaccount_from_id  BankAccount ID to use as the source of the internal wire transfer		{@from body}{@required true}
182
     * @param int     $bankaccount_to_id    BankAccount ID to use as the destination of the internal wire transfer  {@from body}{@required true}
183
     * @param string  $date					Date of the internal wire transfer (UNIX timestamp)						{@from body}{@required true}{@type timestamp}
184
     * @param string  $description			Description of the internal wire transfer								{@from body}{@required true}
185
     * @param float	  $amount				Amount to transfer from the source to the destination BankAccount		{@from body}{@required true}
186
     * @param float	  $amount_to			Amount to transfer to the destination BankAccount (only when accounts does not share the same currency)		{@from body}{@required false}
187
     *
188
     * @url POST    /transfer
189
     *
190
     * @return array
191
     *
192
     * @status 201
193
     *
194
     * @throws RestException 401 Unauthorized: User does not have permission to configure bank accounts
195
	 * @throws RestException 404 Not Found: Either the source or the destination bankaccount for the provided id does not exist
196
     * @throws RestException 422 Unprocessable Entity: Refer to detailed exception message for the cause
197
	 * @throws RestException 500 Internal Server Error: Error(s) returned by the RDBMS
198
     */
199
    public function transfer($bankaccount_from_id = 0, $bankaccount_to_id = 0, $date = null, $description = "", $amount = 0.0, $amount_to = 0.0)
200
    {
201
        if (!DolibarrApiAccess::$user->rights->banque->configurer) {
202
            throw new RestException(401);
203
        }
204
205
        if ($bankaccount_from_id === $bankaccount_to_id) {
206
            throw new RestException(422, 'bankaccount_from_id and bankaccount_to_id must be different !');
207
        }
208
209
        require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
210
211
        $accountfrom = new Account($this->db);
212
        $resultAccountFrom = $accountfrom->fetch($bankaccount_from_id);
213
214
        if ($resultAccountFrom === 0) {
215
            throw new RestException(404, 'The BankAccount for bankaccount_from_id provided does not exist.');
216
        }
217
218
        $accountto = new Account($this->db);
219
        $resultAccountTo = $accountto->fetch($bankaccount_to_id);
220
221
        if ($resultAccountTo === 0) {
222
            throw new RestException(404, 'The BankAccount for bankaccount_to_id provided does not exist.');
223
        }
224
225
        if ($accountto->currency_code == $accountfrom->currency_code)
226
        {
227
            $amount_to = $amount;
228
        }
229
        else
230
        {
231
            if (!$amount_to || empty($amount_to))
232
            {
233
                throw new RestException(422, 'You must provide amount_to value since bankaccount_from and bankaccount_to does not share the same currency.');
234
            }
235
        }
236
237
        $this->db->begin();
238
239
        $error = 0;
240
        $bank_line_id_from = 0;
241
        $bank_line_id_to = 0;
242
        $result = 0;
243
        $user = DolibarrApiAccess::$user;
244
245
        // By default, electronic transfert from bank to bank
246
        $typefrom = 'PRE';
247
        $typeto = 'VIR';
248
249
        if ($accountto->courant == Account::TYPE_CASH || $accountfrom->courant == Account::TYPE_CASH)
250
        {
251
            // This is transfer of change
252
            $typefrom = 'LIQ';
253
            $typeto = 'LIQ';
254
        }
255
256
        /**
257
         * Creating bank line records
258
         */
259
260
        if (!$error) {
261
            $bank_line_id_from = $accountfrom->addline($date, $typefrom, $description, -1 * price2num($amount), '', '', $user);
262
        }
263
        if (!($bank_line_id_from > 0)) {
264
            $error++;
265
        }
266
267
        if (!$error) {
268
            $bank_line_id_to = $accountto->addline($date, $typeto, $description, price2num($amount_to), '', '', $user);
269
        }
270
        if (!($bank_line_id_to > 0)) {
271
            $error++;
272
        }
273
274
        /**
275
         * Creating links between bank line record and its source
276
         */
277
278
        $url = DOL_URL_ROOT.'/compta/bank/line.php?rowid=';
279
        $label = '(banktransfert)';
280
        $type = 'banktransfert';
281
282
        if (!$error) {
283
            $result = $accountfrom->add_url_line($bank_line_id_from, $bank_line_id_to, $url, $label, $type);
284
        }
285
        if (!($result > 0)) {
286
            $error++;
287
        }
288
289
        if (!$error) {
290
            $result = $accountto->add_url_line($bank_line_id_to, $bank_line_id_from, $url, $label, $type);
291
        }
292
        if (!($result > 0)) {
293
            $error++;
294
        }
295
296
        if (!$error)
297
        {
298
            $this->db->commit();
299
300
            return array(
301
                'success' => array(
302
                    'code' => 201,
303
                    'message' => 'Internal wire transfer created successfully.'
304
                )
305
            );
306
        }
307
        else
308
        {
309
            $this->db->rollback();
310
            throw new RestException(500, $accountfrom->error.' '.$accountto->error);
311
        }
312
    }
313
314
    /**
315
     * Update account
316
     *
317
     * @param int    $id              ID of account
318
     * @param array  $request_data    data
319
     * @return int
320
     */
321
    public function put($id, $request_data = null)
322
    {
323
        if (!DolibarrApiAccess::$user->rights->banque->configurer) {
324
            throw new RestException(401);
325
        }
326
327
        $account = new Account($this->db);
328
        $result = $account->fetch($id);
329
        if (!$result) {
330
            throw new RestException(404, 'account not found');
331
        }
332
333
        foreach ($request_data as $field => $value) {
334
            if ($field == 'id') continue;
335
            $account->$field = $value;
336
        }
337
338
        if ($account->update(DolibarrApiAccess::$user) > 0)
339
        {
340
            return $this->get($id);
341
        }
342
        else
343
        {
344
            throw new RestException(500, $account->error);
345
        }
346
    }
347
348
    /**
349
     * Delete account
350
     *
351
     * @param int    $id    ID of account
352
     * @return array
353
     */
354
    public function delete($id)
355
    {
356
        if (!DolibarrApiAccess::$user->rights->banque->configurer) {
357
            throw new RestException(401);
358
        }
359
        $account = new Account($this->db);
360
        $result = $account->fetch($id);
361
        if (!$result) {
362
            throw new RestException(404, 'account not found');
363
        }
364
365
        if ($account->delete(DolibarrApiAccess::$user) < 0) {
366
            throw new RestException(401, 'error when deleting account');
367
        }
368
369
        return array(
370
            'success' => array(
371
                'code' => 200,
372
                'message' => 'account deleted'
373
            )
374
        );
375
    }
376
377
    /**
378
     * Validate fields before creating an object
379
     *
380
     * @param array|null    $data    Data to validate
381
     * @return array
382
     *
383
     * @throws RestException
384
     */
385
    private function _validate($data)
386
    {
387
        $account = array();
388
        foreach (BankAccounts::$FIELDS as $field) {
389
            if (!isset($data[$field]))
390
                throw new RestException(400, "$field field missing");
391
            $account[$field] = $data[$field];
392
        }
393
        return $account;
394
    }
395
396
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
397
    /**
398
     * Clean sensible object datas
399
     *
400
     * @param object    $object    Object to clean
401
     * @return array Array of cleaned object properties
402
     */
403
    protected function _cleanObjectDatas($object)
404
    {
405
        // phpcs:enable
406
        $object = parent::_cleanObjectDatas($object);
407
408
        unset($object->rowid);
409
410
        return $object;
411
    }
412
413
    /**
414
     * Get the list of lines of the account.
415
     *
416
     * @param int $id ID of account
417
     * @return array Array of AccountLine objects
418
     *
419
     * @throws RestException
420
     *
421
     * @url GET {id}/lines
422
	 * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.import_key:<:'20160101')"
423
     */
424
    public function getLines($id, $sqlfilters = '')
425
    {
426
        $list = array();
427
428
        if (!DolibarrApiAccess::$user->rights->banque->lire) {
429
            throw new RestException(401);
430
        }
431
432
        $account = new Account($this->db);
433
        $result = $account->fetch($id);
434
        if (!$result) {
435
            throw new RestException(404, 'account not found');
436
        }
437
438
        $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."bank ";
439
        $sql .= " WHERE fk_account = ".$id;
440
441
		// Add sql filters
442
		if ($sqlfilters)
443
		{
444
			if (!DolibarrApi::_checkFilters($sqlfilters))
445
			{
446
				throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
447
			}
448
			$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
449
			$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
450
		}
451
452
        $sql .= " ORDER BY rowid";
453
454
        $result = $this->db->query($sql);
455
456
        if ($result) {
457
            $num = $this->db->num_rows($result);
458
            for ($i = 0; $i < $num; $i++) {
459
                $obj = $this->db->fetch_object($result);
460
                $accountLine = new AccountLine($this->db);
461
                if ($accountLine->fetch($obj->rowid) > 0) {
462
                    $list[] = $this->_cleanObjectDatas($accountLine);
463
                }
464
            }
465
        } else {
466
            throw new RestException(503, 'Error when retrieving list of account lines: '.$accountLine->error);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $accountLine seems to be never defined.
Loading history...
467
        }
468
469
        return $list;
470
    }
471
472
    /**
473
     * Add a line to an account
474
     *
475
     * @param int    $id            ID of account
476
     * @param int    $date          Payment date (timestamp) {@from body} {@type timestamp}
477
     * @param string $type          Payment mode (TYP,VIR,PRE,LIQ,VAD,CB,CHQ...) {@from body}
478
     * @param string $label         Label {@from body}
479
     * @param float  $amount        Amount (may be 0) {@from body}
480
     * @param int    $category      Category
481
     * @param string $cheque_number Cheque numberl {@from body}
482
     * @param string $cheque_writer Name of cheque writer {@from body}
483
     * @param string $cheque_bank   Bank of cheque writer {@from body}
484
     * @return int  ID of line
485
     *
486
     * @url POST {id}/lines
487
     */
488
    public function addLine($id, $date, $type, $label, $amount, $category = 0, $cheque_number = '', $cheque_writer = '', $cheque_bank = '')
489
    {
490
        if (!DolibarrApiAccess::$user->rights->banque->modifier) {
491
            throw new RestException(401);
492
        }
493
494
        $account = new Account($this->db);
495
        $result = $account->fetch($id);
496
        if (!$result) {
497
            throw new RestException(404, 'account not found');
498
        }
499
500
        $result = $account->addline(
501
            $date,
502
            $type,
503
            $label,
504
            $amount,
505
            $cheque_number,
506
            $category,
507
            DolibarrApiAccess::$user,
508
            $cheque_writer, $cheque_bank
509
        );
510
        if ($result < 0) {
511
            throw new RestException(503, 'Error when adding line to account: '.$account->error);
512
        }
513
        return $result;
514
    }
515
516
    /**
517
     * Add a link to an account line
518
     *
519
     * @param int    $id    		ID of account
520
     * @param int    $line_id       ID of account line
521
     * @param int    $url_id        ID to set in the URL {@from body}
522
     * @param string $url           URL of the link {@from body}
523
     * @param string $label         Label {@from body}
524
     * @param string $type          Type of link ('payment', 'company', 'member', ...) {@from body}
525
     * @return int  ID of link
526
     *
527
     * @url POST {id}/lines/{line_id}/links
528
     */
529
    public function addLink($id, $line_id, $url_id, $url, $label, $type)
530
    {
531
        if (!DolibarrApiAccess::$user->rights->banque->modifier) {
532
            throw new RestException(401);
533
        }
534
535
        $account = new Account($this->db);
536
        $result = $account->fetch($id);
537
        if (!$result) {
538
            throw new RestException(404, 'account not found');
539
        }
540
541
        $accountLine = new AccountLine($this->db);
542
        $result = $accountLine->fetch($line_id);
543
        if (!$result) {
544
            throw new RestException(404, 'account line not found');
545
        }
546
547
        $result = $account->add_url_line($line_id, $url_id, $url, $label, $type);
548
        if ($result < 0) {
549
            throw new RestException(503, 'Error when adding link to account line: '.$account->error);
550
        }
551
        return $result;
552
    }
553
}
554