Passed
Pull Request — dev (#8)
by Rafael
58:47
created

SupplierInvoices::index()   F

Complexity

Conditions 21
Paths 12801

Size

Total Lines 82
Code Lines 51

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 21
eloc 51
nc 12801
nop 8
dl 0
loc 82
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

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:

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) 2015       Jean-François Ferry         <[email protected]>
4
 * Copyright (C) 2016       Laurent Destailleur         <[email protected]>
5
 * Copyright (C) 2023	    Joachim Kueter		        <[email protected]>
6
 * Copyright (C) 2024		MDW							<[email protected]>
7
 * Copyright (C) 2024       Rafael San José             <[email protected]>
8
 *
9
 * This program 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
 * 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 General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21
 */
22
23
namespace Dolibarr\Code\Fourn\Api;
24
25
use Dolibarr\Code\Api\Classes\DolibarrApiAccess;
26
use Dolibarr\Code\Fourn\Classes\FactureFournisseur;
27
use Dolibarr\Core\Base\DolibarrApi;
28
use Luracast\Restler\RestException;
29
30
/**
31
 * API class for supplier invoices
32
 *
33
 * @property DoliDB $db
34
 * @access protected
35
 * @class  DolibarrApiAccess {@requires user,external}
36
 */
37
class SupplierInvoices extends DolibarrApi
38
{
39
    /**
40
     *
41
     * @var array   $FIELDS     Mandatory fields, checked when create and update object
42
     */
43
    public static $FIELDS = array(
44
        'socid',
45
    );
46
47
    /**
48
     * @var FactureFournisseur $invoice {@type FactureFournisseur}
49
     */
50
    public $invoice;
51
52
    /**
53
     * Constructor
54
     */
55
    public function __construct()
56
    {
57
        global $db;
58
        $this->db = $db;
59
        $this->invoice = new FactureFournisseur($this->db);
60
    }
61
62
    /**
63
     * Get properties of a supplier invoice object
64
     *
65
     * Return an array with supplier invoice information
66
     *
67
     * @param   int     $id             ID of supplier invoice
68
     * @return  array                  Object with cleaned properties
69
     *
70
     * @throws  RestException 403
71
     * @throws  RestException 404
72
     */
73
    public function get($id)
74
    {
75
        if (!DolibarrApiAccess::$user->hasRight("fournisseur", "facture", "lire")) {
76
            throw new RestException(403);
77
        }
78
79
        if (!DolibarrApi::_checkAccessToResource('fournisseur', $id, 'facture_fourn', 'facture')) {
80
            throw new RestException(403, 'Access not allowed for login ' . DolibarrApiAccess::$user->login);
81
        }
82
83
        $result = $this->invoice->fetch($id);
84
        if (!$result) {
85
            throw new RestException(404, 'Supplier invoice not found');
86
        }
87
88
        $this->invoice->fetchObjectLinked();
89
        return $this->_cleanObjectDatas($this->invoice);
90
    }
91
92
    /**
93
     * List invoices
94
     *
95
     * Get a list of supplier invoices
96
     *
97
     * @param string    $sortfield        Sort field
98
     * @param string    $sortorder        Sort order
99
     * @param int       $limit            Limit for list
100
     * @param int       $page             Page number
101
     * @param string    $thirdparty_ids   Thirdparty ids to filter invoices of (example '1' or '1,2,3') {@pattern /^[0-9,]*$/i}
102
     * @param string    $status           Filter by invoice status : draft | unpaid | paid | cancelled
103
     * @param string    $sqlfilters       Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.datec:<:'20160101')"
104
     * @param string    $properties       Restrict the data returned to these properties. Ignored if empty. Comma separated list of properties names
105
     * @return array                      Array of invoice objects
106
     *
107
     * @throws RestException
108
     */
109
    public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $status = '', $sqlfilters = '', $properties = '')
110
    {
111
        if (!DolibarrApiAccess::$user->hasRight("fournisseur", "facture", "lire")) {
112
            throw new RestException(403);
113
        }
114
115
        $obj_ret = array();
116
117
        // case of external user, $thirdparty_ids param is ignored and replaced by user's socid
118
        $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids;
119
120
        // If the internal user must only see his customers, force searching by him
121
        $search_sale = 0;
122
        if (!DolibarrApiAccess::$user->hasRight("societe", "client", "voir")) {
123
            $search_sale = DolibarrApiAccess::$user->id;
124
        }
125
126
        $sql = "SELECT t.rowid";
127
        $sql .= " FROM " . MAIN_DB_PREFIX . "facture_fourn AS t";
128
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "facture_fourn_extrafields AS ef ON (ef.fk_object = t.rowid)"; // Modification VMR Global Solutions to include extrafields as search parameters in the API GET call, so we will be able to filter on extrafields
129
        $sql .= ' WHERE t.entity IN (' . getEntity('supplier_invoice') . ')';
130
        if ($socids) {
131
            $sql .= " AND t.fk_soc IN (" . $this->db->sanitize($socids) . ")";
132
        }
133
        // Filter by status
134
        if ($status == 'draft') {
135
            $sql .= " AND t.fk_statut IN (0)";
136
        }
137
        if ($status == 'unpaid') {
138
            $sql .= " AND t.fk_statut IN (1)";
139
        }
140
        if ($status == 'paid') {
141
            $sql .= " AND t.fk_statut IN (2)";
142
        }
143
        if ($status == 'cancelled') {
144
            $sql .= " AND t.fk_statut IN (3)";
145
        }
146
        // Search on sale representative
147
        if ($search_sale && $search_sale != '-1') {
148
            if ($search_sale == -2) {
149
                $sql .= " AND NOT EXISTS (SELECT sc.fk_soc FROM " . MAIN_DB_PREFIX . "societe_commerciaux as sc WHERE sc.fk_soc = t.fk_soc)";
150
            } elseif ($search_sale > 0) {
151
                $sql .= " AND EXISTS (SELECT sc.fk_soc FROM " . MAIN_DB_PREFIX . "societe_commerciaux as sc WHERE sc.fk_soc = t.fk_soc AND sc.fk_user = " . ((int) $search_sale) . ")";
152
            }
153
        }
154
        // Add sql filters
155
        if ($sqlfilters) {
156
            $errormessage = '';
157
            $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
158
            if ($errormessage) {
159
                throw new RestException(400, 'Error when validating parameter sqlfilters -> ' . $errormessage);
160
            }
161
        }
162
163
        $sql .= $this->db->order($sortfield, $sortorder);
164
        if ($limit) {
165
            if ($page < 0) {
166
                $page = 0;
167
            }
168
            $offset = $limit * $page;
169
170
            $sql .= $this->db->plimit($limit + 1, $offset);
171
        }
172
173
        $result = $this->db->query($sql);
174
        if ($result) {
175
            $i = 0;
176
            $num = $this->db->num_rows($result);
177
            $min = min($num, ($limit <= 0 ? $num : $limit));
178
            while ($i < $min) {
179
                $obj = $this->db->fetch_object($result);
180
                $invoice_static = new FactureFournisseur($this->db);
181
                if ($invoice_static->fetch($obj->rowid)) {
182
                    $obj_ret[] = $this->_filterObjectProperties($this->_cleanObjectDatas($invoice_static), $properties);
183
                }
184
                $i++;
185
            }
186
        } else {
187
            throw new RestException(503, 'Error when retrieve supplier invoice list : ' . $this->db->lasterror());
188
        }
189
190
        return $obj_ret;
191
    }
192
193
    /**
194
     * Create supplier invoice object
195
     *
196
     * Note: soc_id = dolibarr_order_id
197
     *
198
     * Example: {'ref': 'auto', 'ref_supplier': '7985630', 'socid': 1, 'note': 'Inserted with Python', 'order_supplier': 1, 'date': '2021-07-28'}
199
     *
200
     * @param array $request_data Request datas
201
     *
202
     * @return int  ID of supplier invoice
203
     *
204
     * @throws RestException 403
205
     * @throws RestException 500    System error
206
     */
207
    public function post($request_data = null)
208
    {
209
        if (!DolibarrApiAccess::$user->hasRight("fournisseur", "facture", "creer")) {
210
            throw new RestException(403, "Insuffisant rights");
211
        }
212
        // Check mandatory fields
213
        $result = $this->_validate($request_data);
214
215
        foreach ($request_data as $field => $value) {
216
            if ($field === 'caller') {
217
                // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
218
                $this->invoice->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
219
                continue;
220
            }
221
222
            $this->invoice->$field = $this->_checkValForAPI($field, $value, $this->invoice);
223
        }
224
        if (!array_key_exists('date', $request_data)) {
225
            $this->invoice->date = dol_now();
226
        }
227
228
        if ($this->invoice->create(DolibarrApiAccess::$user) < 0) {
229
            throw new RestException(500, "Error creating invoice ", array_merge(array($this->invoice->error), $this->invoice->errors));
230
        }
231
        return $this->invoice->id;
232
    }
233
234
    /**
235
     * Update supplier invoice
236
     *
237
     * @param   int     $id                 Id of supplier invoice to update
238
     * @param   array   $request_data       Datas
239
     * @return  Object|false                Updated object
240
     *
241
     * @throws RestException 403
242
     * @throws RestException 404
243
     */
244
    public function put($id, $request_data = null)
245
    {
246
        if (!DolibarrApiAccess::$user->hasRight("fournisseur", "facture", "creer")) {
247
            throw new RestException(403);
248
        }
249
250
        if (!DolibarrApi::_checkAccessToResource('fournisseur', $id, 'facture_fourn', 'facture')) {
251
            throw new RestException(403, 'Access not allowed for login ' . DolibarrApiAccess::$user->login);
252
        }
253
254
        $result = $this->invoice->fetch($id);
255
        if (!$result) {
256
            throw new RestException(404, 'Supplier invoice not found');
257
        }
258
259
        foreach ($request_data as $field => $value) {
260
            if ($field == 'id') {
261
                continue;
262
            }
263
            if ($field === 'caller') {
264
                // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
265
                $this->invoice->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
266
                continue;
267
            }
268
            if ($field == 'array_options' && is_array($value)) {
269
                foreach ($value as $index => $val) {
270
                    $this->invoice->array_options[$index] = $this->_checkValForAPI($field, $val, $this->invoice);
271
                }
272
                continue;
273
            }
274
            $this->invoice->$field = $this->_checkValForAPI($field, $value, $this->invoice);
275
        }
276
277
        if ($this->invoice->update(DolibarrApiAccess::$user)) {
278
            return $this->get($id);
279
        }
280
281
        return false;
282
    }
283
284
    /**
285
     * Delete supplier invoice
286
     *
287
     * @param int   $id Supplier invoice ID
288
     *
289
     * @return array
290
     *
291
     * @throws RestException 403
292
     * @throws RestException 404
293
     * @throws RestException 500    System error
294
     */
295
    public function delete($id)
296
    {
297
        if (!DolibarrApiAccess::$user->hasRight("fournisseur", "facture", "supprimer")) {
298
            throw new RestException(403);
299
        }
300
        if (!DolibarrApi::_checkAccessToResource('fournisseur', $id, 'facture_fourn', 'facture')) {
301
            throw new RestException(403, 'Access not allowed for login ' . DolibarrApiAccess::$user->login);
302
        }
303
        $result = $this->invoice->fetch($id);
304
        if (!$result) {
305
            throw new RestException(404, 'Supplier invoice not found');
306
        }
307
308
        if ($this->invoice->delete(DolibarrApiAccess::$user) < 0) {
309
            throw new RestException(500, 'Error when deleting invoice');
310
        }
311
312
        return array(
313
            'success' => array(
314
                'code' => 200,
315
                'message' => 'Supplier invoice deleted'
316
            )
317
        );
318
    }
319
320
    /**
321
     * Validate an invoice
322
     *
323
     * @param   int $id             Invoice ID
324
     * @param   int $idwarehouse    Warehouse ID
325
     * @param   int $notrigger      1=Does not execute triggers, 0= execute triggers
326
     *
327
     * @url POST    {id}/validate
328
     *
329
     * @return  array
330
     *
331
     * @throws RestException 304
332
     * @throws RestException 403
333
     * @throws RestException 404
334
     * @throws RestException 405
335
     * @throws RestException 500    System error
336
     */
337
    public function validate($id, $idwarehouse = 0, $notrigger = 0)
338
    {
339
        if (!DolibarrApiAccess::$user->hasRight("fournisseur", "facture", "creer")) {
340
            throw new RestException(403);
341
        }
342
343
        if (!DolibarrApi::_checkAccessToResource('fournisseur', $id, 'facture_fourn', 'facture')) {
344
            throw new RestException(403, 'Access not allowed for login ' . DolibarrApiAccess::$user->login);
345
        }
346
347
        $result = $this->invoice->fetch($id);
348
        if (!$result) {
349
            throw new RestException(404, 'Invoice not found');
350
        }
351
352
        $result = $this->invoice->validate(DolibarrApiAccess::$user, '', $idwarehouse, $notrigger);
353
        if ($result == 0) {
354
            throw new RestException(304, 'Error nothing done. The invoice is already validated');
355
        }
356
        if ($result < 0) {
357
            throw new RestException(500, 'Error when validating Invoice: ' . $this->invoice->error);
358
        }
359
360
        return array(
361
            'success' => array(
362
                'code' => 200,
363
                'message' => 'Invoice validated (Ref=' . $this->invoice->ref . ')'
364
            )
365
        );
366
    }
367
368
    /**
369
     * Get list of payments of a given supplier invoice
370
     *
371
     * @param int   $id             Id of SupplierInvoice
372
     *
373
     * @url     GET {id}/payments
374
     *
375
     * @return array
376
     * @throws RestException 400
377
     * @throws RestException 403
378
     * @throws RestException 404
379
     * @throws RestException 405
380
     */
381
    public function getPayments($id)
382
    {
383
        if (empty($id)) {
384
            throw new RestException(400, 'Invoice ID is mandatory');
385
        }
386
387
        if (!DolibarrApiAccess::$user->hasRight("fournisseur", "facture", "lire")) {
388
            throw new RestException(403);
389
        }
390
        if (!DolibarrApi::_checkAccessToResource('fournisseur', $id, 'facture_fourn', 'facture')) {
391
            throw new RestException(403, 'Access not allowed for login ' . DolibarrApiAccess::$user->login);
392
        }
393
394
        $result = $this->invoice->fetch($id);
395
        if (!$result) {
396
            throw new RestException(404, 'Invoice not found');
397
        }
398
399
        $result = $this->invoice->getListOfPayments();
400
        if ($this->invoice->error !== '') {
401
            throw new RestException(405, $this->invoice->error);
402
        }
403
404
        return $result;
405
    }
406
407
408
    /**
409
     * Add payment line to a specific supplier invoice with the remain to pay as amount.
410
     *
411
     * @param int     $id                               Id of invoice
412
     * @param int     $datepaye           {@from body}  Payment date        {@type timestamp}
413
     * @param int     $payment_mode_id    {@from body}  Payment mode ID (look it up via REST GET to /setup/dictionary/payment_types) {@min 1}
414
     * @param string  $closepaidinvoices  {@from body}  Close paid invoices {@choice yes,no}
415
     * @param int     $accountid          {@from body}  Bank account ID (look it up via REST GET to /bankaccounts) {@min 1}
416
     * @param string  $num_payment        {@from body}  Payment number (optional)
417
     * @param string  $comment            {@from body}  Note (optional)
418
     * @param string  $chqemetteur        {@from body}  Payment issuer (mandatory if payment_mode_id corresponds to 'CHQ'-payment type)
419
     * @param string  $chqbank            {@from body}  Issuer bank name (optional)
420
     * @param float   $amount             {@from body}  Amount of payment if we don't want to use the remain to pay
421
     *
422
     * @url     POST {id}/payments
423
     *
424
     * @return int  Payment ID
425
     *
426
     * @throws RestException 400
427
     * @throws RestException 403
428
     * @throws RestException 404
429
     */
430
    public function addPayment($id, $datepaye, $payment_mode_id, $closepaidinvoices, $accountid, $num_payment = '', $comment = '', $chqemetteur = '', $chqbank = '', $amount = null)
431
    {
432
        if (empty($id)) {
433
            throw new RestException(400, 'Invoice ID is mandatory');
434
        }
435
436
        if (!DolibarrApiAccess::$user->hasRight("fournisseur", "facture", "creer")) {
437
            throw new RestException(403);
438
        }
439
        if (!DolibarrApi::_checkAccessToResource('fournisseur', $id, 'facture_fourn', 'facture')) {
440
            throw new RestException(403, 'Access not allowed for login ' . DolibarrApiAccess::$user->login);
441
        }
442
443
        $result = $this->invoice->fetch($id);
444
        if (!$result) {
445
            throw new RestException(404, 'Invoice not found');
446
        }
447
448
        if (isModEnabled("bank")) {
449
            if (empty($accountid)) {
450
                throw new RestException(400, 'Bank account ID is mandatory');
451
            }
452
        }
453
454
        if (empty($payment_mode_id)) {
455
            throw new RestException(400, 'Payment mode ID is mandatory');
456
        }
457
458
        if (null !== $amount && $amount > 0) {
459
            // We use the amount given in parameter
460
            $paymentamount = $amount;
461
        } else {
462
            // We calculate the remain to pay, and use it as amount
463
            $totalpaid = $this->invoice->getSommePaiement();
464
            $totaldeposits = $this->invoice->getSumDepositsUsed();
465
            $paymentamount = price2num($this->invoice->total_ttc - $totalpaid - $totaldeposits, 'MT');
466
        }
467
468
        $this->db->begin();
469
470
        $amounts = array();
471
        $multicurrency_amounts = array();
472
473
        $paymentamount = (float) price2num($paymentamount, 'MT');
474
475
        $amounts[$id] = $paymentamount;
476
477
        // Multicurrency
478
        $newvalue = (float) price2num($this->invoice->multicurrency_total_ttc, 'MT');
479
        $multicurrency_amounts[$id] = $newvalue;
480
481
        // Creation of payment line
482
        $paiement = new PaiementFourn($this->db);
483
        $paiement->datepaye     = $datepaye;
484
        $paiement->amounts      = $amounts; // Array with all payments dispatching with invoice id
485
        $paiement->multicurrency_amounts = $multicurrency_amounts; // Array with all payments dispatching
486
        $paiement->paiementid = $payment_mode_id;
487
        $paiement->paiementcode = (string) dol_getIdFromCode($this->db, $payment_mode_id, 'c_paiement', 'id', 'code', 1);
488
        $paiement->num_payment = $num_payment;
489
        $paiement->note_public = $comment;
490
491
        $paiement_id = $paiement->create(DolibarrApiAccess::$user, ($closepaidinvoices == 'yes' ? 1 : 0)); // This include closing invoices
492
        if ($paiement_id < 0) {
493
            $this->db->rollback();
494
            throw new RestException(400, 'Payment error : ' . $paiement->error);
495
        }
496
497
        if (isModEnabled("bank")) {
498
            $result = $paiement->addPaymentToBank(DolibarrApiAccess::$user, 'payment_supplier', '(SupplierInvoicePayment)', $accountid, $chqemetteur, $chqbank);
499
            if ($result < 0) {
500
                $this->db->rollback();
501
                throw new RestException(400, 'Add payment to bank error : ' . $paiement->error);
502
            }
503
        }
504
505
        $this->db->commit();
506
507
        return $paiement_id;
508
    }
509
510
    /**
511
     * Get lines of a supplier invoice
512
     *
513
     * @param int   $id             Id of supplier invoice
514
     *
515
     * @url GET {id}/lines
516
     *
517
     * @return array
518
     *
519
     * @throws RestException 403
520
     * @throws RestException 404
521
     */
522
    public function getLines($id)
523
    {
524
        if (!DolibarrApiAccess::$user->hasRight("fournisseur", "facture", "creer")) {
525
            throw new RestException(403);
526
        }
527
        if (!DolibarrApi::_checkAccessToResource('fournisseur', $id, 'facture_fourn', 'facture')) {
528
            throw new RestException(403, 'Access not allowed for login ' . DolibarrApiAccess::$user->login);
529
        }
530
531
        $result = $this->invoice->fetch($id);
532
        if (!$result) {
533
            throw new RestException(404, 'Supplier invoice not found');
534
        }
535
536
        $this->invoice->fetch_lines();
537
        $result = array();
538
        foreach ($this->invoice->lines as $line) {
539
            array_push($result, $this->_cleanObjectDatas($line));
540
        }
541
        return $result;
542
    }
543
544
    /**
545
     * Add a line to given supplier invoice
546
     *
547
     * Note: socid = dolibarr_order_id, pu_ht = net price, remise = discount
548
     *
549
     * Example: {'socid': 1, 'qty': 1, 'pu_ht': 21.0, 'tva_tx': 25.0, 'fk_product': '1189', 'product_type': 0, 'remise_percent': 1.0, 'vat_src_code': None}
550
     *
551
     * @param int   $id             Id of supplier invoice to update
552
     * @param array $request_data   supplier invoice line data
553
     *
554
     * @url POST {id}/lines
555
     *
556
     * @return int|bool
557
     *
558
     * @throws RestException 403
559
     * @throws RestException 404
560
     */
561
    public function postLine($id, $request_data = null)
562
    {
563
        if (!DolibarrApiAccess::$user->hasRight("fournisseur", "facture", "creer")) {
564
            throw new RestException(403);
565
        }
566
567
        if (!DolibarrApi::_checkAccessToResource('fournisseur', $id, 'facture_fourn', 'facture')) {
568
            throw new RestException(403, 'Access not allowed for login ' . DolibarrApiAccess::$user->login);
569
        }
570
571
        $result = $this->invoice->fetch($id);
572
        if (!$result) {
573
            throw new RestException(404, 'Supplier invoice not found');
574
        }
575
576
        $request_data = (object) $request_data;
577
578
        $request_data->description = sanitizeVal($request_data->description, 'restricthtml');
579
        $request_data->ref_supplier = sanitizeVal($request_data->ref_supplier);
580
581
        $updateRes = $this->invoice->addline(
582
            $request_data->description,
583
            $request_data->pu_ht,
584
            $request_data->tva_tx,
585
            $request_data->localtax1_tx,
586
            $request_data->localtax2_tx,
587
            $request_data->qty,
588
            $request_data->fk_product,
589
            $request_data->remise_percent,
590
            $request_data->date_start,
591
            $request_data->date_end,
592
            $request_data->fk_code_ventilation,
593
            $request_data->info_bits,
594
            $request_data->price_base_type ? $request_data->price_base_type : 'HT',
595
            $request_data->product_type,
596
            $request_data->rang,
597
            false,
598
            $request_data->array_options,
599
            $request_data->fk_unit,
600
            $request_data->origin_id,
601
            $request_data->multicurrency_subprice,
602
            $request_data->ref_supplier,
603
            $request_data->special_code
604
        );
605
606
        if ($updateRes < 0) {
607
            throw new RestException(400, 'Unable to insert the new line. Check your inputs. ' . $this->invoice->error);
608
        }
609
610
        return $updateRes;
611
    }
612
613
    /**
614
     * Update a line to a given supplier invoice
615
     *
616
     * @param int   $id             Id of supplier invoice to update
617
     * @param int   $lineid         Id of line to update
618
     * @param array $request_data   InvoiceLine data
619
     *
620
     * @url PUT {id}/lines/{lineid}
621
     *
622
     * @return object
623
     *
624
     * @throws RestException 403 Not allowed
625
     * @throws RestException 404 Not found
626
     * @throws RestException 304 Error
627
     */
628
    public function putLine($id, $lineid, $request_data = null)
629
    {
630
        if (!DolibarrApiAccess::$user->hasRight("fournisseur", "facture", "creer")) {
631
            throw new RestException(403);
632
        }
633
634
        if (!DolibarrApi::_checkAccessToResource('fournisseur', $id, 'facture_fourn', 'facture')) {
635
            throw new RestException(403, 'Access not allowed for login ' . DolibarrApiAccess::$user->login);
636
        }
637
638
        $result = $this->invoice->fetch($id);
639
        if (!$result) {
640
            throw new RestException(404, 'Supplier invoice not found');
641
        }
642
643
        $request_data = (object) $request_data;
644
645
        $request_data->description = sanitizeVal($request_data->description, 'restricthtml');
646
        $request_data->ref_supplier = sanitizeVal($request_data->ref_supplier);
647
648
        $updateRes = $this->invoice->updateline(
649
            $lineid,
650
            $request_data->description,
651
            $request_data->pu_ht,
652
            $request_data->tva_tx,
653
            $request_data->localtax1_tx,
654
            $request_data->localtax2_tx,
655
            $request_data->qty,
656
            $request_data->fk_product,
657
            $request_data->price_base_type ? $request_data->price_base_type : 'HT',
658
            $request_data->info_bits,
659
            $request_data->product_type,
660
            $request_data->remise_percent,
661
            false,
662
            $request_data->date_start,
663
            $request_data->date_end,
664
            $request_data->array_options,
665
            $request_data->fk_unit,
666
            $request_data->multicurrency_subprice,
667
            $request_data->ref_supplier,
668
            $request_data->rang
669
        );
670
671
        if ($updateRes > 0) {
672
            $result = $this->get($id);
673
            unset($result->line);
674
            return $this->_cleanObjectDatas($result);
675
        } else {
676
            throw new RestException(304, $this->invoice->error);
677
        }
678
    }
679
680
    /**
681
     * Deletes a line of a given supplier invoice
682
     *
683
     * @param int   $id             Id of supplier invoice
684
     * @param int   $lineid         Id of the line to delete
685
     *
686
     * @url     DELETE {id}/lines/{lineid}
687
     *
688
     * @return array
689
     *
690
     * @throws RestException 400 Bad parameters
691
     * @throws RestException 403 Not allowed
692
     * @throws RestException 404 Not found
693
     * @throws RestException 405 Error
694
     */
695
    public function deleteLine($id, $lineid)
696
    {
697
        if (empty($lineid)) {
698
            throw new RestException(400, 'Line ID is mandatory');
699
        }
700
701
        if (!DolibarrApiAccess::$user->hasRight("fournisseur", "facture", "creer")) {
702
            throw new RestException(403);
703
        }
704
        if (!DolibarrApi::_checkAccessToResource('fournisseur', $id, 'facture_fourn', 'facture')) {
705
            throw new RestException(403, 'Access not allowed for login ' . DolibarrApiAccess::$user->login);
706
        }
707
708
        $result = $this->invoice->fetch($id);
709
        if (!$result) {
710
            throw new RestException(404, 'Supplier invoice not found');
711
        }
712
713
        // TODO Check the lineid $lineid is a line of object
714
715
        $updateRes = $this->invoice->deleteLine($lineid);
716
        if ($updateRes > 0) {
717
            return array(
718
                'success' => array(
719
                    'code' => 200,
720
                    'message' => 'line ' . $lineid . ' deleted'
721
                )
722
            );
723
        } else {
724
            throw new RestException(405, $this->invoice->error);
725
        }
726
    }
727
728
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
729
    /**
730
     * Clean sensible object datas
731
     *
732
     * @param   Object  $object     Object to clean
733
     * @return  Object              Object with cleaned properties
734
     */
735
    protected function _cleanObjectDatas($object)
736
    {
737
		// phpcs:enable
738
        $object = parent::_cleanObjectDatas($object);
739
740
        unset($object->rowid);
741
        unset($object->barcode_type);
742
        unset($object->barcode_type_code);
743
        unset($object->barcode_type_label);
744
        unset($object->barcode_type_coder);
745
746
        return $object;
747
    }
748
749
    /**
750
     * Validate fields before create or update object
751
     *
752
     * @param array $data   Datas to validate
753
     * @return array
754
     *
755
     * @throws RestException
756
     */
757
    private function _validate($data)
758
    {
759
        $invoice = array();
760
        foreach (SupplierInvoices::$FIELDS as $field) {
761
            if (!isset($data[$field])) {
762
                throw new RestException(400, "$field field missing");
763
            }
764
            $invoice[$field] = $data[$field];
765
        }
766
        return $invoice;
767
    }
768
}
769