Passed
Push — EXTRACT_CLASSES ( c25e41...9f3ede )
by Rafael
55:18
created

SupplierInvoices::deleteLine()   A

Complexity

Conditions 6
Paths 6

Size

Total Lines 30
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

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