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

SupplierInvoices::get()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 9
nc 4
nop 1
dl 0
loc 17
rs 9.9666
c 0
b 0
f 0
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