dolibarr  17.0.4
api_supplier_invoices.class.php
1 <?php
2 /* Copyright (C) 2015 Jean-Fran├žois Ferry <jfefe@aternatik.fr>
3  * Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <https://www.gnu.org/licenses/>.
17  */
18 
19 use Luracast\Restler\RestException;
20 
21 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
22 require_once DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php';
23 
32 {
37  public static $FIELDS = array(
38  'socid',
39  );
40 
44  public $invoice;
45 
49  public function __construct()
50  {
51  global $db;
52  $this->db = $db;
53  $this->invoice = new FactureFournisseur($this->db);
54  }
55 
66  public function get($id)
67  {
68  if (!DolibarrApiAccess::$user->rights->fournisseur->facture->lire) {
69  throw new RestException(401);
70  }
71 
72  $result = $this->invoice->fetch($id);
73  if (!$result) {
74  throw new RestException(404, 'Supplier invoice not found');
75  }
76 
77  if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->invoice->id, 'facture_fourn', 'facture')) {
78  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
79  }
80 
81  $this->invoice->fetchObjectLinked();
82  return $this->_cleanObjectDatas($this->invoice);
83  }
84 
101  public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $status = '', $sqlfilters = '')
102  {
103  global $db;
104 
105  if (!DolibarrApiAccess::$user->rights->fournisseur->facture->lire) {
106  throw new RestException(401);
107  }
108 
109  $obj_ret = array();
110 
111  // case of external user, $thirdparty_ids param is ignored and replaced by user's socid
112  $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids;
113 
114  // If the internal user must only see his customers, force searching by him
115  $search_sale = 0;
116  if (!DolibarrApiAccess::$user->rights->societe->client->voir) {
117  $search_sale = DolibarrApiAccess::$user->id;
118  }
119 
120  $sql = "SELECT t.rowid";
121  // We need these fields in order to filter by sale (including the case where the user can only see his prospects)
122  if (!DolibarrApiAccess::$user->rights->societe->client->voir || $search_sale > 0) {
123  $sql .= ", sc.fk_soc, sc.fk_user";
124  }
125  $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as t";
126 
127  // We need this table joined to the select in order to filter by sale
128  if (!DolibarrApiAccess::$user->rights->societe->client->voir || $search_sale > 0) {
129  $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
130  }
131 
132  $sql .= ' WHERE t.entity IN ('.getEntity('supplier_invoice').')';
133  if (!DolibarrApiAccess::$user->rights->societe->client->voir || $search_sale > 0) {
134  $sql .= " AND t.fk_soc = sc.fk_soc";
135  }
136  if ($socids) {
137  $sql .= " AND t.fk_soc IN (".$this->db->sanitize($socids).")";
138  }
139  if ($search_sale > 0) {
140  $sql .= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale
141  }
142 
143  // Filter by status
144  if ($status == 'draft') {
145  $sql .= " AND t.fk_statut IN (0)";
146  }
147  if ($status == 'unpaid') {
148  $sql .= " AND t.fk_statut IN (1)";
149  }
150  if ($status == 'paid') {
151  $sql .= " AND t.fk_statut IN (2)";
152  }
153  if ($status == 'cancelled') {
154  $sql .= " AND t.fk_statut IN (3)";
155  }
156  // Insert sale filter
157  if ($search_sale > 0) {
158  $sql .= " AND sc.fk_user = ".((int) $search_sale);
159  }
160  // Add sql filters
161  if ($sqlfilters) {
162  $errormessage = '';
163  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
164  if ($errormessage) {
165  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
166  }
167  }
168 
169  $sql .= $this->db->order($sortfield, $sortorder);
170  if ($limit) {
171  if ($page < 0) {
172  $page = 0;
173  }
174  $offset = $limit * $page;
175 
176  $sql .= $this->db->plimit($limit + 1, $offset);
177  }
178 
179  $result = $this->db->query($sql);
180  if ($result) {
181  $i = 0;
182  $num = $this->db->num_rows($result);
183  $min = min($num, ($limit <= 0 ? $num : $limit));
184  while ($i < $min) {
185  $obj = $this->db->fetch_object($result);
186  $invoice_static = new FactureFournisseur($this->db);
187  if ($invoice_static->fetch($obj->rowid)) {
188  $obj_ret[] = $this->_cleanObjectDatas($invoice_static);
189  }
190  $i++;
191  }
192  } else {
193  throw new RestException(503, 'Error when retrieve supplier invoice list : '.$this->db->lasterror());
194  }
195  if (!count($obj_ret)) {
196  throw new RestException(404, 'No supplier invoice found');
197  }
198  return $obj_ret;
199  }
200 
215  public function post($request_data = null)
216  {
217  if (!DolibarrApiAccess::$user->rights->fournisseur->facture->creer) {
218  throw new RestException(401, "Insuffisant rights");
219  }
220  // Check mandatory fields
221  $result = $this->_validate($request_data);
222 
223  foreach ($request_data as $field => $value) {
224  $this->invoice->$field = $value;
225  }
226  if (!array_key_exists('date', $request_data)) {
227  $this->invoice->date = dol_now();
228  }
229 
230  if ($this->invoice->create(DolibarrApiAccess::$user) < 0) {
231  throw new RestException(500, "Error creating order", array_merge(array($this->invoice->error), $this->invoice->errors));
232  }
233  return $this->invoice->id;
234  }
235 
247  public function put($id, $request_data = null)
248  {
249  if (!DolibarrApiAccess::$user->rights->fournisseur->facture->creer) {
250  throw new RestException(401);
251  }
252 
253  $result = $this->invoice->fetch($id);
254  if (!$result) {
255  throw new RestException(404, 'Supplier invoice not found');
256  }
257 
258  if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->invoice->id, 'facture_fourn', 'facture')) {
259  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
260  }
261 
262  foreach ($request_data as $field => $value) {
263  if ($field == 'id') {
264  continue;
265  }
266  $this->invoice->$field = $value;
267  }
268 
269  if ($this->invoice->update($id, DolibarrApiAccess::$user)) {
270  return $this->get($id);
271  }
272 
273  return false;
274  }
275 
287  public function delete($id)
288  {
289  if (!DolibarrApiAccess::$user->rights->fournisseur->facture->supprimer) {
290  throw new RestException(401);
291  }
292  $result = $this->invoice->fetch($id);
293  if (!$result) {
294  throw new RestException(404, 'Supplier invoice not found');
295  }
296 
297  if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->invoice->id, 'facture_fourn', 'facture')) {
298  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
299  }
300 
301  if ($this->invoice->delete(DolibarrApiAccess::$user) < 0) {
302  throw new RestException(500, 'Error when deleting invoice');
303  }
304 
305  return array(
306  'success' => array(
307  'code' => 200,
308  'message' => 'Supplier invoice deleted'
309  )
310  );
311  }
312 
330  public function validate($id, $idwarehouse = 0, $notrigger = 0)
331  {
332  if (!DolibarrApiAccess::$user->rights->fournisseur->facture->creer) {
333  throw new RestException(401);
334  }
335  $result = $this->invoice->fetch($id);
336  if (!$result) {
337  throw new RestException(404, 'Invoice not found');
338  }
339 
340  if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->invoice->id, 'facture_fourn', 'facture')) {
341  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
342  }
343 
344  $result = $this->invoice->validate(DolibarrApiAccess::$user, '', $idwarehouse, $notrigger);
345  if ($result == 0) {
346  throw new RestException(304, 'Error nothing done. The invoice is already validated');
347  }
348  if ($result < 0) {
349  throw new RestException(500, 'Error when validating Invoice: '.$this->invoice->error);
350  }
351 
352  return array(
353  'success' => array(
354  'code' => 200,
355  'message' => 'Invoice validated (Ref='.$this->invoice->ref.')'
356  )
357  );
358  }
359 
373  public function getPayments($id)
374  {
375  if (!DolibarrApiAccess::$user->rights->fournisseur->facture->lire) {
376  throw new RestException(401);
377  }
378  if (empty($id)) {
379  throw new RestException(400, 'Invoice ID is mandatory');
380  }
381 
382  $result = $this->invoice->fetch($id);
383  if (!$result) {
384  throw new RestException(404, 'Invoice not found');
385  }
386 
387  if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->invoice->id, 'facture_fourn', 'facture')) {
388  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
389  }
390 
391  $result = $this->invoice->getListOfPayments();
392  if ($result < 0) {
393  throw new RestException(405, $this->invoice->error);
394  }
395 
396  return $result;
397  }
398 
399 
420  public function addPayment($id, $datepaye, $payment_mode_id, $closepaidinvoices, $accountid, $num_payment = '', $comment = '', $chqemetteur = '', $chqbank = '')
421  {
422  global $conf;
423 
424  if (!DolibarrApiAccess::$user->rights->fournisseur->facture->creer) {
425  throw new RestException(403);
426  }
427  if (empty($id)) {
428  throw new RestException(400, 'Invoice ID is mandatory');
429  }
430 
431  $result = $this->invoice->fetch($id);
432  if (!$result) {
433  throw new RestException(404, 'Invoice not found');
434  }
435 
436  if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->invoice->id, 'facture_fourn', 'facture')) {
437  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
438  }
439 
440  if (isModEnabled("banque")) {
441  if (empty($accountid)) {
442  throw new RestException(400, 'Bank account ID is mandatory');
443  }
444  }
445 
446  if (empty($payment_mode_id)) {
447  throw new RestException(400, 'Payment mode ID is mandatory');
448  }
449 
450  // Calculate amount to pay
451  $totalpaid = $this->invoice->getSommePaiement();
452  $totaldeposits = $this->invoice->getSumDepositsUsed();
453  $resteapayer = price2num($this->invoice->total_ttc - $totalpaid - $totaldeposits, 'MT');
454 
455  $this->db->begin();
456 
457  $amounts = array();
458  $multicurrency_amounts = array();
459 
460  $resteapayer = price2num($resteapayer, 'MT');
461  $amounts[$id] = $resteapayer;
462 
463  // Multicurrency
464  $newvalue = price2num($this->invoice->multicurrency_total_ttc, 'MT');
465  $multicurrency_amounts[$id] = $newvalue;
466 
467  // Creation of payment line
468  $paiement = new PaiementFourn($this->db);
469  $paiement->datepaye = $datepaye;
470  $paiement->amounts = $amounts; // Array with all payments dispatching with invoice id
471  $paiement->multicurrency_amounts = $multicurrency_amounts; // Array with all payments dispatching
472  $paiement->paiementid = $payment_mode_id;
473  $paiement->paiementcode = dol_getIdFromCode($this->db, $payment_mode_id, 'c_paiement', 'id', 'code', 1);
474  $paiement->num_payment = $num_payment;
475  $paiement->note_public = $comment;
476 
477  $paiement_id = $paiement->create(DolibarrApiAccess::$user, ($closepaidinvoices == 'yes' ? 1 : 0)); // This include closing invoices
478  if ($paiement_id < 0) {
479  $this->db->rollback();
480  throw new RestException(400, 'Payment error : '.$paiement->error);
481  }
482 
483  if (isModEnabled("banque")) {
484  $result = $paiement->addPaymentToBank(DolibarrApiAccess::$user, 'payment_supplier', '(SupplierInvoicePayment)', $accountid, $chqemetteur, $chqbank);
485  if ($result < 0) {
486  $this->db->rollback();
487  throw new RestException(400, 'Add payment to bank error : '.$paiement->error);
488  }
489  }
490 
491  $this->db->commit();
492 
493  return $paiement_id;
494  }
495 
505  public function getLines($id)
506  {
507  if (!DolibarrApiAccess::$user->rights->fournisseur->facture->creer) {
508  throw new RestException(401);
509  }
510 
511  $result = $this->invoice->fetch($id);
512  if (!$result) {
513  throw new RestException(404, 'Supplier invoice not found');
514  }
515 
516  if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->invoice->id, 'facture_fourn', 'facture')) {
517  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
518  }
519  $this->invoice->fetch_lines();
520  $result = array();
521  foreach ($this->invoice->lines as $line) {
522  array_push($result, $this->_cleanObjectDatas($line));
523  }
524  return $result;
525  }
526 
541  public function postLine($id, $request_data = null)
542  {
543  if (!DolibarrApiAccess::$user->rights->fournisseur->facture->creer) {
544  throw new RestException(401);
545  }
546 
547  $result = $this->invoice->fetch($id);
548  if (!$result) {
549  throw new RestException(404, 'Supplier invoice not found');
550  }
551 
552  if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->invoice->id, 'facture_fourn', 'facture')) {
553  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
554  }
555 
556  $request_data = (object) $request_data;
557 
558  $request_data->description = sanitizeVal($request_data->description, 'restricthtml');
559  $request_data->ref_supplier = sanitizeVal($request_data->ref_supplier);
560 
561  $updateRes = $this->invoice->addline(
562  $request_data->description,
563  $request_data->pu_ht,
564  $request_data->tva_tx,
565  $request_data->localtax1_tx,
566  $request_data->localtax2_tx,
567  $request_data->qty,
568  $request_data->fk_product,
569  $request_data->remise_percent,
570  $request_data->date_start,
571  $request_data->date_end,
572  $request_data->ventil,
573  $request_data->info_bits,
574  $request_data->price_base_type ? $request_data->price_base_type : 'HT',
575  $request_data->product_type,
576  $request_data->rang,
577  false,
578  $request_data->array_options,
579  $request_data->fk_unit,
580  $request_data->origin_id,
581  $request_data->multicurrency_subprice,
582  $request_data->ref_supplier,
583  $request_data->special_code
584  );
585 
586  if ($updateRes < 0) {
587  throw new RestException(400, 'Unable to insert the new line. Check your inputs. '.$this->invoice->error);
588  }
589 
590  return $updateRes;
591  }
592 
608  public function putLine($id, $lineid, $request_data = null)
609  {
610  if (!DolibarrApiAccess::$user->rights->fournisseur->facture->creer) {
611  throw new RestException(401);
612  }
613 
614  $result = $this->invoice->fetch($id);
615  if (!$result) {
616  throw new RestException(404, 'Supplier invoice not found');
617  }
618 
619  if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->invoice->id, 'facture_fourn', 'facture')) {
620  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
621  }
622 
623  $request_data = (object) $request_data;
624 
625  $request_data->description = sanitizeVal($request_data->description, 'restricthtml');
626  $request_data->ref_supplier = sanitizeVal($request_data->ref_supplier);
627 
628  $updateRes = $this->invoice->updateline(
629  $lineid,
630  $request_data->description,
631  $request_data->pu_ht,
632  $request_data->tva_tx,
633  $request_data->localtax1_tx,
634  $request_data->localtax2_tx,
635  $request_data->qty,
636  $request_data->fk_product,
637  $request_data->price_base_type ? $request_data->price_base_type : 'HT',
638  $request_data->info_bits,
639  $request_data->product_type,
640  $request_data->remise_percent,
641  false,
642  $request_data->date_start,
643  $request_data->date_end,
644  $request_data->array_options,
645  $request_data->fk_unit,
646  $request_data->multicurrency_subprice,
647  $request_data->ref_supplier,
648  $request_data->rang
649  );
650 
651  if ($updateRes > 0) {
652  $result = $this->get($id);
653  unset($result->line);
654  return $this->_cleanObjectDatas($result);
655  } else {
656  throw new RestException(304, $this->invoice->error);
657  }
658  }
659 
675  public function deleteLine($id, $lineid)
676  {
677  if (!DolibarrApiAccess::$user->rights->fournisseur->facture->creer) {
678  throw new RestException(401);
679  }
680 
681  $result = $this->invoice->fetch($id);
682  if (!$result) {
683  throw new RestException(404, 'Supplier invoice not found');
684  }
685 
686  if (empty($lineid)) {
687  throw new RestException(400, 'Line ID is mandatory');
688  }
689 
690  if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->invoice->id, 'facture_fourn', 'facture')) {
691  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
692  }
693 
694  // TODO Check the lineid $lineid is a line of ojbect
695 
696  $updateRes = $this->invoice->deleteline($lineid);
697  if ($updateRes > 0) {
698  return $this->get($id);
699  } else {
700  throw new RestException(405, $this->invoice->error);
701  }
702  }
703 
704  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
711  protected function _cleanObjectDatas($object)
712  {
713  // phpcs:enable
714  $object = parent::_cleanObjectDatas($object);
715 
716  unset($object->rowid);
717  unset($object->barcode_type);
718  unset($object->barcode_type_code);
719  unset($object->barcode_type_label);
720  unset($object->barcode_type_coder);
721 
722  return $object;
723  }
724 
733  private function _validate($data)
734  {
735  $invoice = array();
736  foreach (SupplierInvoices::$FIELDS as $field) {
737  if (!isset($data[$field])) {
738  throw new RestException(400, "$field field missing");
739  }
740  $invoice[$field] = $data[$field];
741  }
742  return $invoice;
743  }
744 }
Class for API REST v1.
Definition: api.class.php:31
static _checkAccessToResource($resource, $resource_id=0, $dbtablename='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid')
Check access by user to a given resource.
Definition: api.class.php:283
Class to manage suppliers invoices.
Class to manage payments for supplier invoices.
validate($id, $idwarehouse=0, $notrigger=0)
Validate an invoice.
addPayment($id, $datepaye, $payment_mode_id, $closepaidinvoices, $accountid, $num_payment='', $comment='', $chqemetteur='', $chqbank='')
Add payment line to a specific supplier invoice with the remain to pay as amount.
deleteLine($id, $lineid)
Deletes a line of a given supplier invoice.
getLines($id)
Get lines of a supplier invoice.
getPayments($id)
Get list of payments of a given supplier invoice.
_cleanObjectDatas($object)
Clean sensible object datas.
index($sortfield="t.rowid", $sortorder='ASC', $limit=100, $page=0, $thirdparty_ids='', $status='', $sqlfilters='')
List invoices.
post($request_data=null)
Create supplier invoice object.
postLine($id, $request_data=null)
Add a line to given supplier invoice.
put($id, $request_data=null)
Update supplier invoice.
_validate($data)
Validate fields before create or update object.
putLine($id, $lineid, $request_data=null)
Update a line to a given supplier invoice.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
forgeSQLFromUniversalSearchCriteria($filter, &$error='')
forgeSQLFromUniversalSearchCriteria
dol_now($mode='auto')
Return date for now.
dol_getIdFromCode($db, $key, $tablename, $fieldkey='code', $fieldid='id', $entityfilter=0, $filters='')
Return an id or code from a code or id.
sanitizeVal($out='', $check='alphanohtml', $filter=null, $options=null)
Return a sanitized or empty value after checking value against a rule.
isModEnabled($module)
Is Dolibarr module enabled.
$conf db
API class for accounts.
Definition: inc.php:41