dolibarr  13.0.2
api_invoices.class.php
1 <?php
2 /* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
3 /* Copyright (C) 2020 Thibault FOUCART <support@ptibogxiv.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.'/compta/facture/class/facture.class.php';
22 
29 class Invoices extends DolibarrApi
30 {
35  static $FIELDS = array(
36  'socid',
37  );
38 
42  public $invoice;
43 
47  public function __construct()
48  {
49  global $db, $conf;
50  $this->db = $db;
51  $this->invoice = new Facture($this->db);
52  }
53 
65  public function get($id, $contact_list = 1)
66  {
67  return $this->_fetch($id, '', '', $contact_list);
68  }
69 
83  public function getByRef($ref, $contact_list = 1)
84  {
85  return $this->_fetch('', $ref, '', $contact_list);
86  }
87 
101  public function getByRefExt($ref_ext, $contact_list = 1)
102  {
103  return $this->_fetch('', '', $ref_ext, $contact_list);
104  }
105 
119  private function _fetch($id, $ref = '', $ref_ext = '', $contact_list = 1)
120  {
121  if (!DolibarrApiAccess::$user->rights->facture->lire) {
122  throw new RestException(401);
123  }
124 
125  $result = $this->invoice->fetch($id, $ref, $ref_ext);
126  if (!$result) {
127  throw new RestException(404, 'Invoice not found');
128  }
129 
130  // Get payment details
131  $this->invoice->totalpaid = $this->invoice->getSommePaiement();
132  $this->invoice->totalcreditnotes = $this->invoice->getSumCreditNotesUsed();
133  $this->invoice->totaldeposits = $this->invoice->getSumDepositsUsed();
134  $this->invoice->remaintopay = price2num($this->invoice->total_ttc - $this->invoice->totalpaid - $this->invoice->totalcreditnotes - $this->invoice->totaldeposits, 'MT');
135 
136  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
137  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
138  }
139 
140  // Add external contacts ids
141  $this->invoice->contacts_ids = $this->invoice->liste_contact(-1, 'external', $contact_list);
142 
143  $this->invoice->fetchObjectLinked();
144  return $this->_cleanObjectDatas($this->invoice);
145  }
146 
164  public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $status = '', $sqlfilters = '')
165  {
166  global $db, $conf;
167 
168  $obj_ret = array();
169 
170  // case of external user, $thirdparty_ids param is ignored and replaced by user's socid
171  $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids;
172 
173  // If the internal user must only see his customers, force searching by him
174  $search_sale = 0;
175  if (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id;
176 
177  $sql = "SELECT t.rowid";
178  if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects)
179  $sql .= " FROM ".MAIN_DB_PREFIX."facture as t";
180 
181  if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale
182 
183  $sql .= ' WHERE t.entity IN ('.getEntity('invoice').')';
184  if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= " AND t.fk_soc = sc.fk_soc";
185  if ($socids) $sql .= " AND t.fk_soc IN (".$socids.")";
186 
187  if ($search_sale > 0) $sql .= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale
188 
189  // Filter by status
190  if ($status == 'draft') $sql .= " AND t.fk_statut IN (0)";
191  if ($status == 'unpaid') $sql .= " AND t.fk_statut IN (1)";
192  if ($status == 'paid') $sql .= " AND t.fk_statut IN (2)";
193  if ($status == 'cancelled') $sql .= " AND t.fk_statut IN (3)";
194  // Insert sale filter
195  if ($search_sale > 0)
196  {
197  $sql .= " AND sc.fk_user = ".$search_sale;
198  }
199  // Add sql filters
200  if ($sqlfilters)
201  {
202  if (!DolibarrApi::_checkFilters($sqlfilters))
203  {
204  throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
205  }
206  $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
207  $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
208  }
209 
210  $sql .= $this->db->order($sortfield, $sortorder);
211  if ($limit)
212  {
213  if ($page < 0)
214  {
215  $page = 0;
216  }
217  $offset = $limit * $page;
218 
219  $sql .= $this->db->plimit($limit + 1, $offset);
220  }
221 
222  $result = $this->db->query($sql);
223  if ($result)
224  {
225  $i = 0;
226  $num = $this->db->num_rows($result);
227  $min = min($num, ($limit <= 0 ? $num : $limit));
228  while ($i < $min)
229  {
230  $obj = $this->db->fetch_object($result);
231  $invoice_static = new Facture($this->db);
232  if ($invoice_static->fetch($obj->rowid))
233  {
234  // Get payment details
235  $invoice_static->totalpaid = $invoice_static->getSommePaiement();
236  $invoice_static->totalcreditnotes = $invoice_static->getSumCreditNotesUsed();
237  $invoice_static->totaldeposits = $invoice_static->getSumDepositsUsed();
238  $invoice_static->remaintopay = price2num($invoice_static->total_ttc - $invoice_static->totalpaid - $invoice_static->totalcreditnotes - $invoice_static->totaldeposits, 'MT');
239 
240  // Add external contacts ids
241  $invoice_static->contacts_ids = $invoice_static->liste_contact(-1, 'external', 1);
242 
243  $obj_ret[] = $this->_cleanObjectDatas($invoice_static);
244  }
245  $i++;
246  }
247  } else {
248  throw new RestException(503, 'Error when retrieve invoice list : '.$this->db->lasterror());
249  }
250  if (!count($obj_ret)) {
251  throw new RestException(404, 'No invoice found');
252  }
253  return $obj_ret;
254  }
255 
262  public function post($request_data = null)
263  {
264  if (!DolibarrApiAccess::$user->rights->facture->creer) {
265  throw new RestException(401, "Insuffisant rights");
266  }
267  // Check mandatory fields
268  $result = $this->_validate($request_data);
269 
270  foreach ($request_data as $field => $value) {
271  $this->invoice->$field = $value;
272  }
273  if (!array_key_exists('date', $request_data)) {
274  $this->invoice->date = dol_now();
275  }
276  /* We keep lines as an array
277  if (isset($request_data["lines"])) {
278  $lines = array();
279  foreach ($request_data["lines"] as $line) {
280  array_push($lines, (object) $line);
281  }
282  $this->invoice->lines = $lines;
283  }*/
284 
285  if ($this->invoice->create(DolibarrApiAccess::$user, 0, (empty($request_data["date_lim_reglement"]) ? 0 : $request_data["date_lim_reglement"])) < 0) {
286  throw new RestException(500, "Error creating invoice", array_merge(array($this->invoice->error), $this->invoice->errors));
287  }
288  return $this->invoice->id;
289  }
290 
305  public function createInvoiceFromOrder($orderid)
306  {
307 
308  require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
309 
310  if (!DolibarrApiAccess::$user->rights->commande->lire) {
311  throw new RestException(401);
312  }
313  if (!DolibarrApiAccess::$user->rights->facture->creer) {
314  throw new RestException(401);
315  }
316  if (empty($orderid)) {
317  throw new RestException(400, 'Order ID is mandatory');
318  }
319 
320  $order = new Commande($this->db);
321  $result = $order->fetch($orderid);
322  if (!$result) {
323  throw new RestException(404, 'Order not found');
324  }
325 
326  $result = $this->invoice->createFromOrder($order, DolibarrApiAccess::$user);
327  if ($result < 0) {
328  throw new RestException(405, $this->invoice->error);
329  }
330  $this->invoice->fetchObjectLinked();
331  return $this->_cleanObjectDatas($this->invoice);
332  }
333 
343  public function getLines($id)
344  {
345  if (!DolibarrApiAccess::$user->rights->facture->lire) {
346  throw new RestException(401);
347  }
348 
349  $result = $this->invoice->fetch($id);
350  if (!$result) {
351  throw new RestException(404, 'Invoice not found');
352  }
353 
354  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
355  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
356  }
357  $this->invoice->getLinesArray();
358  $result = array();
359  foreach ($this->invoice->lines as $line) {
360  array_push($result, $this->_cleanObjectDatas($line));
361  }
362  return $result;
363  }
364 
380  public function putLine($id, $lineid, $request_data = null)
381  {
382  if (!DolibarrApiAccess::$user->rights->facture->creer) {
383  throw new RestException(401);
384  }
385 
386  $result = $this->invoice->fetch($id);
387  if (!$result) {
388  throw new RestException(404, 'Invoice not found');
389  }
390 
391  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
392  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
393  }
394  $request_data = (object) $request_data;
395  $updateRes = $this->invoice->updateline(
396  $lineid,
397  $request_data->desc,
398  $request_data->subprice,
399  $request_data->qty,
400  $request_data->remise_percent,
401  $request_data->date_start,
402  $request_data->date_end,
403  $request_data->tva_tx,
404  $request_data->localtax1_tx,
405  $request_data->localtax2_tx,
406  'HT',
407  $request_data->info_bits,
408  $request_data->product_type,
409  $request_data->fk_parent_line,
410  0,
411  $request_data->fk_fournprice,
412  $request_data->pa_ht,
413  $request_data->label,
414  $request_data->special_code,
415  $request_data->array_options,
416  $request_data->situation_percent,
417  $request_data->fk_unit,
418  $request_data->multicurrency_subprice,
419  0,
420  $request_data->ref_ext
421  );
422 
423  if ($updateRes > 0) {
424  $result = $this->get($id);
425  unset($result->line);
426  return $this->_cleanObjectDatas($result);
427  } else {
428  throw new RestException(304, $this->invoice->error);
429  }
430  }
431 
446  public function postContact($id, $contactid, $type)
447  {
448  if (!DolibarrApiAccess::$user->rights->facture->creer) {
449  throw new RestException(401);
450  }
451 
452  $result = $this->invoice->fetch($id);
453 
454  if (!$result) {
455  throw new RestException(404, 'Invoice not found');
456  }
457 
458  if (!in_array($type, array('BILLING', 'SHIPPING', 'CUSTOMER'), true)) {
459  throw new RestException(500, 'Availables types: BILLING, SHIPPING OR CUSTOMER');
460  }
461 
462  if (!DolibarrApi::_checkAccessToResource('invoice', $this->invoice->id)) {
463  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
464  }
465 
466  $result = $this->invoice->add_contact($contactid, $type, 'external');
467 
468  if (!$result) {
469  throw new RestException(500, 'Error when added the contact');
470  }
471 
472  return $this->_cleanObjectDatas($this->invoice);
473  }
474 
490  public function deleteContact($id, $contactid, $type)
491  {
492  if (!DolibarrApiAccess::$user->rights->facture->creer) {
493  throw new RestException(401);
494  }
495 
496  $result = $this->invoice->fetch($id);
497 
498  if (!$result) {
499  throw new RestException(404, 'Invoice not found');
500  }
501 
502  if (!DolibarrApi::_checkAccessToResource('invoice', $this->invoice->id)) {
503  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
504  }
505 
506  $contacts = $this->invoice->liste_contact();
507 
508  foreach ($contacts as $contact) {
509  if ($contact['id'] == $contactid && $contact['code'] == $type) {
510  $result = $this->invoice->delete_contact($contact['rowid']);
511 
512  if (!$result) {
513  throw new RestException(500, 'Error when deleted the contact');
514  }
515  }
516  }
517 
518  return $this->_cleanObjectDatas($this->invoice);
519  }
520 
536  public function deleteLine($id, $lineid)
537  {
538 
539  if (!DolibarrApiAccess::$user->rights->facture->creer) {
540  throw new RestException(401);
541  }
542  if (empty($lineid)) {
543  throw new RestException(400, 'Line ID is mandatory');
544  }
545 
546  if (!DolibarrApi::_checkAccessToResource('facture', $id)) {
547  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
548  }
549 
550  $result = $this->invoice->fetch($id);
551  if (!$result) {
552  throw new RestException(404, 'Invoice not found');
553  }
554 
555  // TODO Check the lineid $lineid is a line of ojbect
556 
557  $updateRes = $this->invoice->deleteline($lineid);
558  if ($updateRes > 0) {
559  return $this->get($id);
560  } else {
561  throw new RestException(405, $this->invoice->error);
562  }
563  }
564 
572  public function put($id, $request_data = null)
573  {
574  if (!DolibarrApiAccess::$user->rights->facture->creer) {
575  throw new RestException(401);
576  }
577 
578  $result = $this->invoice->fetch($id);
579  if (!$result) {
580  throw new RestException(404, 'Invoice not found');
581  }
582 
583  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
584  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
585  }
586 
587  foreach ($request_data as $field => $value) {
588  if ($field == 'id') continue;
589  $this->invoice->$field = $value;
590  }
591 
592  // update bank account
593  if (!empty($this->invoice->fk_account))
594  {
595  if ($this->invoice->setBankAccount($this->invoice->fk_account) == 0) {
596  throw new RestException(400, $this->invoice->error);
597  }
598  }
599 
600  if ($this->invoice->update(DolibarrApiAccess::$user))
601  return $this->get($id);
602 
603  return false;
604  }
605 
612  public function delete($id)
613  {
614  if (!DolibarrApiAccess::$user->rights->facture->supprimer) {
615  throw new RestException(401);
616  }
617  $result = $this->invoice->fetch($id);
618  if (!$result) {
619  throw new RestException(404, 'Invoice not found');
620  }
621 
622  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
623  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
624  }
625 
626  $result = $this->invoice->delete(DolibarrApiAccess::$user);
627  if ($result < 0)
628  {
629  throw new RestException(500);
630  }
631 
632  return array(
633  'success' => array(
634  'code' => 200,
635  'message' => 'Invoice deleted'
636  )
637  );
638  }
639 
663  public function postLine($id, $request_data = null)
664  {
665  if (!DolibarrApiAccess::$user->rights->facture->creer) {
666  throw new RestException(401);
667  }
668 
669  $result = $this->invoice->fetch($id);
670  if (!$result) {
671  throw new RestException(404, 'Invoice not found');
672  }
673 
674  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
675  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
676  }
677 
678  $request_data = (object) $request_data;
679 
680  // Reset fk_parent_line for no child products and special product
681  if (($request_data->product_type != 9 && empty($request_data->fk_parent_line)) || $request_data->product_type == 9) {
682  $request_data->fk_parent_line = 0;
683  }
684 
685  // calculate pa_ht
686  $marginInfos = getMarginInfos($request_data->subprice, $request_data->remise_percent, $request_data->tva_tx, $request_data->localtax1_tx, $request_data->localtax2_tx, $request_data->fk_fournprice, $request_data->pa_ht);
687  $pa_ht = $marginInfos[0];
688 
689  $updateRes = $this->invoice->addline(
690  $request_data->desc,
691  $request_data->subprice,
692  $request_data->qty,
693  $request_data->tva_tx,
694  $request_data->localtax1_tx,
695  $request_data->localtax2_tx,
696  $request_data->fk_product,
697  $request_data->remise_percent,
698  $request_data->date_start,
699  $request_data->date_end,
700  $request_data->fk_code_ventilation,
701  $request_data->info_bits,
702  $request_data->fk_remise_except,
703  'HT',
704  0,
705  $request_data->product_type,
706  $request_data->rang,
707  $request_data->special_code,
708  $request_data->origin,
709  $request_data->origin_id,
710  $request_data->fk_parent_line,
711  empty($request_data->fk_fournprice) ?null:$request_data->fk_fournprice,
712  $pa_ht,
713  $request_data->label,
714  $request_data->array_options,
715  $request_data->situation_percent,
716  $request_data->fk_prev_id,
717  $request_data->fk_unit,
718  0,
719  $request_data->ref_ext
720  );
721 
722  if ($updateRes < 0) {
723  throw new RestException(400, 'Unable to insert the new line. Check your inputs. '.$this->invoice->error);
724  }
725 
726  return $updateRes;
727  }
728 
748  public function addContact($id, $fk_socpeople, $type_contact, $source, $notrigger = 0)
749  {
750  if (!DolibarrApiAccess::$user->rights->facture->creer) {
751  throw new RestException(401);
752  }
753  $result = $this->invoice->fetch($id);
754  if (!$result) {
755  throw new RestException(404, 'Invoice not found');
756  }
757 
758  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
759  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
760  }
761 
762  $result = $this->invoice->add_contact($fk_socpeople, $type_contact, $source, $notrigger);
763  if ($result < 0) {
764  throw new RestException(500, 'Error : '.$this->invoice->error);
765  }
766 
767  $result = $this->invoice->fetch($id);
768  if (!$result) {
769  throw new RestException(404, 'Invoice not found');
770  }
771 
772  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
773  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
774  }
775 
776  return $this->_cleanObjectDatas($this->invoice);
777  }
778 
779 
780 
797  public function settodraft($id, $idwarehouse = -1)
798  {
799  if (!DolibarrApiAccess::$user->rights->facture->creer) {
800  throw new RestException(401);
801  }
802  $result = $this->invoice->fetch($id);
803  if (!$result) {
804  throw new RestException(404, 'Invoice not found');
805  }
806 
807  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
808  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
809  }
810 
811  $result = $this->invoice->setDraft(DolibarrApiAccess::$user, $idwarehouse);
812  if ($result == 0) {
813  throw new RestException(304, 'Nothing done.');
814  }
815  if ($result < 0) {
816  throw new RestException(500, 'Error : '.$this->invoice->error);
817  }
818 
819  $result = $this->invoice->fetch($id);
820  if (!$result) {
821  throw new RestException(404, 'Invoice not found');
822  }
823 
824  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
825  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
826  }
827 
828  return $this->_cleanObjectDatas($this->invoice);
829  }
830 
831 
849  public function validate($id, $idwarehouse = 0, $notrigger = 0)
850  {
851  if (!DolibarrApiAccess::$user->rights->facture->creer) {
852  throw new RestException(401);
853  }
854  $result = $this->invoice->fetch($id);
855  if (!$result) {
856  throw new RestException(404, 'Invoice not found');
857  }
858 
859  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
860  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
861  }
862 
863  $result = $this->invoice->validate(DolibarrApiAccess::$user, '', $idwarehouse, $notrigger);
864  if ($result == 0) {
865  throw new RestException(304, 'Error nothing done. May be object is already validated');
866  }
867  if ($result < 0) {
868  throw new RestException(500, 'Error when validating Invoice: '.$this->invoice->error);
869  }
870 
871  $result = $this->invoice->fetch($id);
872  if (!$result) {
873  throw new RestException(404, 'Invoice not found');
874  }
875 
876  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
877  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
878  }
879 
880  return $this->_cleanObjectDatas($this->invoice);
881  }
882 
899  public function settopaid($id, $close_code = '', $close_note = '')
900  {
901  if (!DolibarrApiAccess::$user->rights->facture->creer) {
902  throw new RestException(401);
903  }
904  $result = $this->invoice->fetch($id);
905  if (!$result) {
906  throw new RestException(404, 'Invoice not found');
907  }
908 
909  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
910  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
911  }
912 
913  $result = $this->invoice->set_paid(DolibarrApiAccess::$user, $close_code, $close_note);
914  if ($result == 0) {
915  throw new RestException(304, 'Error nothing done. May be object is already validated');
916  }
917  if ($result < 0) {
918  throw new RestException(500, 'Error : '.$this->invoice->error);
919  }
920 
921 
922  $result = $this->invoice->fetch($id);
923  if (!$result) {
924  throw new RestException(404, 'Invoice not found');
925  }
926 
927  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
928  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
929  }
930 
931  return $this->_cleanObjectDatas($this->invoice);
932  }
933 
934 
949  public function settounpaid($id)
950  {
951  if (!DolibarrApiAccess::$user->rights->facture->creer) {
952  throw new RestException(401);
953  }
954  $result = $this->invoice->fetch($id);
955  if (!$result) {
956  throw new RestException(404, 'Invoice not found');
957  }
958 
959  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
960  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
961  }
962 
963  $result = $this->invoice->set_unpaid(DolibarrApiAccess::$user);
964  if ($result == 0) {
965  throw new RestException(304, 'Nothing done');
966  }
967  if ($result < 0) {
968  throw new RestException(500, 'Error : '.$this->invoice->error);
969  }
970 
971 
972  $result = $this->invoice->fetch($id);
973  if (!$result) {
974  throw new RestException(404, 'Invoice not found');
975  }
976 
977  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
978  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
979  }
980 
981  return $this->_cleanObjectDatas($this->invoice);
982  }
983 
993  public function getDiscount($id)
994  {
995  require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
996 
997  if (!DolibarrApiAccess::$user->rights->facture->lire) {
998  throw new RestException(401);
999  }
1000 
1001  $result = $this->invoice->fetch($id);
1002  if (!$result) {
1003  throw new RestException(404, 'Invoice not found');
1004  }
1005 
1006  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
1007  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1008  }
1009 
1010  $discountcheck = new DiscountAbsolute($this->db);
1011  $result = $discountcheck->fetch(0, $this->invoice->id);
1012 
1013  if ($result == 0) {
1014  throw new RestException(404, 'Discount not found');
1015  }
1016  if ($result < 0) {
1017  throw new RestException(500, $discountcheck->error);
1018  }
1019 
1020  return parent::_cleanObjectDatas($discountcheck);
1021  }
1022 
1036  public function markAsCreditAvailable($id)
1037  {
1038  require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
1039 
1040  if (!DolibarrApiAccess::$user->rights->facture->creer) {
1041  throw new RestException(401);
1042  }
1043 
1044  $result = $this->invoice->fetch($id);
1045  if (!$result) {
1046  throw new RestException(404, 'Invoice not found');
1047  }
1048 
1049  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
1050  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1051  }
1052 
1053  if ($this->invoice->paye) {
1054  throw new RestException(500, 'Alreay paid');
1055  }
1056 
1057  $this->invoice->fetch($id);
1058  $this->invoice->fetch_thirdparty();
1059 
1060  // Check if there is already a discount (protection to avoid duplicate creation when resubmit post)
1061  $discountcheck = new DiscountAbsolute($this->db);
1062  $result = $discountcheck->fetch(0, $this->invoice->id);
1063 
1064  $canconvert = 0;
1065  if ($this->invoice->type == Facture::TYPE_DEPOSIT && empty($discountcheck->id)) $canconvert = 1; // we can convert deposit into discount if deposit is payed (completely, partially or not at all) and not already converted (see real condition into condition used to show button converttoreduc)
1066  if (($this->invoice->type == Facture::TYPE_CREDIT_NOTE || $this->invoice->type == Facture::TYPE_STANDARD) && $this->invoice->paye == 0 && empty($discountcheck->id)) $canconvert = 1; // we can convert credit note into discount if credit note is not payed back and not already converted and amount of payment is 0 (see real condition into condition used to show button converttoreduc)
1067  if ($canconvert)
1068  {
1069  $this->db->begin();
1070 
1071  $amount_ht = $amount_tva = $amount_ttc = array();
1072  $multicurrency_amount_ht = $multicurrency_amount_tva = $multicurrency_amount_ttc = array();
1073 
1074  // Loop on each vat rate
1075  $i = 0;
1076  foreach ($this->invoice->lines as $line)
1077  {
1078  if ($line->product_type < 9 && $line->total_ht != 0) // Remove lines with product_type greater than or equal to 9
1079  { // no need to create discount if amount is null
1080  $amount_ht[$line->tva_tx] += $line->total_ht;
1081  $amount_tva[$line->tva_tx] += $line->total_tva;
1082  $amount_ttc[$line->tva_tx] += $line->total_ttc;
1083  $multicurrency_amount_ht[$line->tva_tx] += $line->multicurrency_total_ht;
1084  $multicurrency_amount_tva[$line->tva_tx] += $line->multicurrency_total_tva;
1085  $multicurrency_amount_ttc[$line->tva_tx] += $line->multicurrency_total_ttc;
1086  $i++;
1087  }
1088  }
1089 
1090  // Insert one discount by VAT rate category
1091  $discount = new DiscountAbsolute($this->db);
1092  if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) {
1093  $discount->description = '(CREDIT_NOTE)';
1094  } elseif ($this->invoice->type == Facture::TYPE_DEPOSIT) {
1095  $discount->description = '(DEPOSIT)';
1096  } elseif ($this->invoice->type == Facture::TYPE_STANDARD || $this->invoice->type == Facture::TYPE_REPLACEMENT || $this->invoice->type == Facture::TYPE_SITUATION) {
1097  $discount->description = '(EXCESS RECEIVED)';
1098  } else {
1099  throw new RestException(500, 'Cant convert to reduc an Invoice of this type');
1100  }
1101 
1102  $discount->fk_soc = $this->invoice->socid;
1103  $discount->fk_facture_source = $this->invoice->id;
1104 
1105  $error = 0;
1106 
1107  if ($this->invoice->type == Facture::TYPE_STANDARD || $this->invoice->type == Facture::TYPE_REPLACEMENT || $this->invoice->type == Facture::TYPE_SITUATION)
1108  {
1109  // If we're on a standard invoice, we have to get excess received to create a discount in TTC without VAT
1110 
1111  // Total payments
1112  $sql = 'SELECT SUM(pf.amount) as total_payments';
1113  $sql .= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf, '.MAIN_DB_PREFIX.'paiement as p';
1114  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as c ON p.fk_paiement = c.id';
1115  $sql .= ' WHERE pf.fk_facture = '.$this->invoice->id;
1116  $sql .= ' AND pf.fk_paiement = p.rowid';
1117  $sql .= ' AND p.entity IN ('.getEntity('invoice').')';
1118  $resql = $this->db->query($sql);
1119  if (!$resql) dol_print_error($this->db);
1120 
1121  $res = $this->db->fetch_object($resql);
1122  $total_payments = $res->total_payments;
1123 
1124  // Total credit note and deposit
1125  $total_creditnote_and_deposit = 0;
1126  $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,";
1127  $sql .= " re.description, re.fk_facture_source";
1128  $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re";
1129  $sql .= " WHERE fk_facture = ".$this->invoice->id;
1130  $resql = $this->db->query($sql);
1131  if (!empty($resql)) {
1132  while ($obj = $this->db->fetch_object($resql)) $total_creditnote_and_deposit += $obj->amount_ttc;
1133  } else dol_print_error($this->db);
1134 
1135  $discount->amount_ht = $discount->amount_ttc = $total_payments + $total_creditnote_and_deposit - $this->invoice->total_ttc;
1136  $discount->amount_tva = 0;
1137  $discount->tva_tx = 0;
1138 
1139  $result = $discount->create(DolibarrApiAccess::$user);
1140  if ($result < 0)
1141  {
1142  $error++;
1143  }
1144  }
1145  if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE || $this->invoice->type == Facture::TYPE_DEPOSIT)
1146  {
1147  foreach ($amount_ht as $tva_tx => $xxx)
1148  {
1149  $discount->amount_ht = abs($amount_ht[$tva_tx]);
1150  $discount->amount_tva = abs($amount_tva[$tva_tx]);
1151  $discount->amount_ttc = abs($amount_ttc[$tva_tx]);
1152  $discount->multicurrency_amount_ht = abs($multicurrency_amount_ht[$tva_tx]);
1153  $discount->multicurrency_amount_tva = abs($multicurrency_amount_tva[$tva_tx]);
1154  $discount->multicurrency_amount_ttc = abs($multicurrency_amount_ttc[$tva_tx]);
1155  $discount->tva_tx = abs($tva_tx);
1156 
1157  $result = $discount->create(DolibarrApiAccess::$user);
1158  if ($result < 0)
1159  {
1160  $error++;
1161  break;
1162  }
1163  }
1164  }
1165 
1166  if (empty($error))
1167  {
1168  if ($this->invoice->type != Facture::TYPE_DEPOSIT) {
1169  // Classe facture
1170  $result = $this->invoice->set_paid(DolibarrApiAccess::$user);
1171  if ($result >= 0)
1172  {
1173  $this->db->commit();
1174  } else {
1175  $this->db->rollback();
1176  throw new RestException(500, 'Could not set paid');
1177  }
1178  } else {
1179  $this->db->commit();
1180  }
1181  } else {
1182  $this->db->rollback();
1183  throw new RestException(500, 'Discount creation error');
1184  }
1185  }
1186 
1187  return $this->_cleanObjectDatas($this->invoice);
1188  }
1189 
1207  public function useDiscount($id, $discountid)
1208  {
1209 
1210  if (!DolibarrApiAccess::$user->rights->facture->creer) {
1211  throw new RestException(401);
1212  }
1213  if (empty($id)) {
1214  throw new RestException(400, 'Invoice ID is mandatory');
1215  }
1216  if (empty($discountid)) {
1217  throw new RestException(400, 'Discount ID is mandatory');
1218  }
1219 
1220  if (!DolibarrApi::_checkAccessToResource('facture', $id)) {
1221  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1222  }
1223 
1224  $result = $this->invoice->fetch($id);
1225  if (!$result) {
1226  throw new RestException(404, 'Invoice not found');
1227  }
1228 
1229  $result = $this->invoice->insert_discount($discountid);
1230  if ($result < 0) {
1231  throw new RestException(405, $this->invoice->error);
1232  }
1233 
1234  return $result;
1235  }
1236 
1254  public function useCreditNote($id, $discountid)
1255  {
1256 
1257  require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
1258 
1259  if (!DolibarrApiAccess::$user->rights->facture->creer) {
1260  throw new RestException(401);
1261  }
1262  if (empty($id)) {
1263  throw new RestException(400, 'Invoice ID is mandatory');
1264  }
1265  if (empty($discountid)) {
1266  throw new RestException(400, 'Credit ID is mandatory');
1267  }
1268 
1269  if (!DolibarrApi::_checkAccessToResource('facture', $id)) {
1270  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1271  }
1272  $discount = new DiscountAbsolute($this->db);
1273  $result = $discount->fetch($discountid);
1274  if (!$result) {
1275  throw new RestException(404, 'Credit not found');
1276  }
1277 
1278  $result = $discount->link_to_invoice(0, $id);
1279  if ($result < 0) {
1280  throw new RestException(405, $discount->error);
1281  }
1282 
1283  return $result;
1284  }
1285 
1300  public function getPayments($id)
1301  {
1302 
1303  if (!DolibarrApiAccess::$user->rights->facture->lire) {
1304  throw new RestException(401);
1305  }
1306  if (empty($id)) {
1307  throw new RestException(400, 'Invoice ID is mandatory');
1308  }
1309 
1310  if (!DolibarrApi::_checkAccessToResource('facture', $id)) {
1311  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1312  }
1313 
1314  $result = $this->invoice->fetch($id);
1315  if (!$result) {
1316  throw new RestException(404, 'Invoice not found');
1317  }
1318 
1319  $result = $this->invoice->getListOfPayments();
1320  if ($result < 0) {
1321  throw new RestException(405, $this->invoice->error);
1322  }
1323 
1324  return $result;
1325  }
1326 
1327 
1349  public function addPayment($id, $datepaye, $paymentid, $closepaidinvoices, $accountid, $num_payment = '', $comment = '', $chqemetteur = '', $chqbank = '')
1350  {
1351  global $conf;
1352 
1353  require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
1354 
1355  if (!DolibarrApiAccess::$user->rights->facture->creer) {
1356  throw new RestException(403);
1357  }
1358  if (empty($id)) {
1359  throw new RestException(400, 'Invoice ID is mandatory');
1360  }
1361 
1362  if (!DolibarrApi::_checkAccessToResource('facture', $id)) {
1363  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1364  }
1365 
1366  if (!empty($conf->banque->enabled)) {
1367  if (empty($accountid)) {
1368  throw new RestException(400, 'Account ID is mandatory');
1369  }
1370  }
1371 
1372  if (empty($paymentid)) {
1373  throw new RestException(400, 'Payment ID or Payment Code is mandatory');
1374  }
1375 
1376 
1377  $result = $this->invoice->fetch($id);
1378  if (!$result) {
1379  throw new RestException(404, 'Invoice not found');
1380  }
1381 
1382  // Calculate amount to pay
1383  $totalpaye = $this->invoice->getSommePaiement();
1384  $totalcreditnotes = $this->invoice->getSumCreditNotesUsed();
1385  $totaldeposits = $this->invoice->getSumDepositsUsed();
1386  $resteapayer = price2num($this->invoice->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits, 'MT');
1387 
1388  $this->db->begin();
1389 
1390  $amounts = array();
1391  $multicurrency_amounts = array();
1392 
1393  // Clean parameters amount if payment is for a credit note
1394  if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) {
1395  $resteapayer = price2num($resteapayer, 'MT');
1396  $amounts[$id] = -$resteapayer;
1397  // Multicurrency
1398  $newvalue = price2num($this->invoice->multicurrency_total_ttc, 'MT');
1399  $multicurrency_amounts[$id] = -$newvalue;
1400  } else {
1401  $resteapayer = price2num($resteapayer, 'MT');
1402  $amounts[$id] = $resteapayer;
1403  // Multicurrency
1404  $newvalue = price2num($this->invoice->multicurrency_total_ttc, 'MT');
1405  $multicurrency_amounts[$id] = $newvalue;
1406  }
1407 
1408 
1409  // Creation of payment line
1410  $paymentobj = new Paiement($this->db);
1411  $paymentobj->datepaye = $datepaye;
1412  $paymentobj->amounts = $amounts; // Array with all payments dispatching with invoice id
1413  $paymentobj->multicurrency_amounts = $multicurrency_amounts; // Array with all payments dispatching
1414  $paymentobj->paiementid = $paymentid;
1415  $paymentobj->paiementcode = dol_getIdFromCode($this->db, $paymentid, 'c_paiement', 'id', 'code', 1);
1416  $paymentobj->num_payment = $num_payment;
1417  $paymentobj->note_private = $comment;
1418 
1419  $payment_id = $paymentobj->create(DolibarrApiAccess::$user, ($closepaidinvoices == 'yes' ? 1 : 0)); // This include closing invoices
1420  if ($payment_id < 0)
1421  {
1422  $this->db->rollback();
1423  throw new RestException(400, 'Payment error : '.$paymentobj->error);
1424  }
1425 
1426  if (!empty($conf->banque->enabled)) {
1427  $label = '(CustomerInvoicePayment)';
1428 
1429  if ($paymentobj->paiementcode == 'CHQ' && empty($chqemetteur)) {
1430  throw new RestException(400, 'Emetteur is mandatory when payment code is '.$paymentobj->paiementcode);
1431  }
1432  if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) $label = '(CustomerInvoicePaymentBack)'; // Refund of a credit note
1433  $result = $paymentobj->addPaymentToBank(DolibarrApiAccess::$user, 'payment', $label, $accountid, $chqemetteur, $chqbank);
1434  if ($result < 0)
1435  {
1436  $this->db->rollback();
1437  throw new RestException(400, 'Add payment to bank error : '.$paymentobj->error);
1438  }
1439  }
1440 
1441  $this->db->commit();
1442 
1443  return $payment_id;
1444  }
1445 
1471  public function addPaymentDistributed($arrayofamounts, $datepaye, $paymentid, $closepaidinvoices, $accountid, $num_payment = '', $comment = '', $chqemetteur = '', $chqbank = '', $ref_ext = '', $accepthigherpayment = false)
1472  {
1473  global $conf;
1474 
1475  require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
1476 
1477  if (!DolibarrApiAccess::$user->rights->facture->creer) {
1478  throw new RestException(403);
1479  }
1480  foreach ($arrayofamounts as $id => $amount) {
1481  if (empty($id)) {
1482  throw new RestException(400, 'Invoice ID is mandatory. Fill the invoice id and amount into arrayofamounts parameter. For example: {"1": "99.99", "2": "10"}');
1483  }
1484  if (!DolibarrApi::_checkAccessToResource('facture', $id)) {
1485  throw new RestException(403, 'Access not allowed on invoice ID '.$id.' for login '.DolibarrApiAccess::$user->login);
1486  }
1487  }
1488 
1489  if (!empty($conf->banque->enabled)) {
1490  if (empty($accountid)) {
1491  throw new RestException(400, 'Account ID is mandatory');
1492  }
1493  }
1494  if (empty($paymentid)) {
1495  throw new RestException(400, 'Payment ID or Payment Code is mandatory');
1496  }
1497 
1498  $this->db->begin();
1499 
1500  $amounts = array();
1501  $multicurrency_amounts = array();
1502 
1503  // Loop on each invoice to pay
1504  foreach ($arrayofamounts as $id => $amountarray)
1505  {
1506  $result = $this->invoice->fetch($id);
1507  if (!$result) {
1508  $this->db->rollback();
1509  throw new RestException(404, 'Invoice ID '.$id.' not found');
1510  }
1511 
1512  if (($amountarray["amount"] == "remain" || $amountarray["amount"] > 0) && ($amountarray["multicurrency_amount"] == "remain" || $amountarray["multicurrency_amount"] > 0)) {
1513  $this->db->rollback();
1514  throw new RestException(400, 'Payment in both currency '.$id.' ( amount: '.$amountarray["amount"].', multicurrency_amount: '.$amountarray["multicurrency_amount"].')');
1515  }
1516 
1517  $is_multicurrency = 0;
1518  $total_ttc = $this->invoice->total_ttc;
1519 
1520  if ($amountarray["multicurrency_amount"] > 0 || $amountarray["multicurrency_amount"] == "remain") {
1521  $is_multicurrency = 1;
1522  $total_ttc = $this->invoice->multicurrency_total_ttc;
1523  }
1524 
1525  // Calculate amount to pay
1526  $totalpaye = $this->invoice->getSommePaiement($is_multicurrency);
1527  $totalcreditnotes = $this->invoice->getSumCreditNotesUsed($is_multicurrency);
1528  $totaldeposits = $this->invoice->getSumDepositsUsed($is_multicurrency);
1529  $remainstopay = $amount = price2num($total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits, 'MT');
1530 
1531  if (!$is_multicurrency && $amountarray["amount"] != 'remain')
1532  {
1533  $amount = price2num($amountarray["amount"], 'MT');
1534  }
1535 
1536  if ($is_multicurrency && $amountarray["multicurrency_amount"] != 'remain')
1537  {
1538  $amount = price2num($amountarray["multicurrency_amount"], 'MT');
1539  }
1540 
1541  if ($amount > $remainstopay && !$accepthigherpayment) {
1542  $this->db->rollback();
1543  throw new RestException(400, 'Payment amount on invoice ID '.$id.' ('.$amount.') is higher than remain to pay ('.$remainstopay.')');
1544  }
1545 
1546  if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) {
1547  $amount = -$amount;
1548  }
1549 
1550  if ($is_multicurrency) {
1551  $amounts[$id] = null;
1552  // Multicurrency
1553  $multicurrency_amounts[$id] = $amount;
1554  } else {
1555  $amounts[$id] = $amount;
1556  // Multicurrency
1557  $multicurrency_amounts[$id] = null;
1558  }
1559  }
1560 
1561  // Creation of payment line
1562  $paymentobj = new Paiement($this->db);
1563  $paymentobj->datepaye = $datepaye;
1564  $paymentobj->amounts = $amounts; // Array with all payments dispatching with invoice id
1565  $paymentobj->multicurrency_amounts = $multicurrency_amounts; // Array with all payments dispatching
1566  $paymentobj->paiementid = $paymentid;
1567  $paymentobj->paiementcode = dol_getIdFromCode($this->db, $paymentid, 'c_paiement', 'id', 'code', 1);
1568  $paymentobj->num_payment = $num_payment;
1569  $paymentobj->note_private = $comment;
1570  $paymentobj->ref_ext = $ref_ext;
1571  $payment_id = $paymentobj->create(DolibarrApiAccess::$user, ($closepaidinvoices == 'yes' ? 1 : 0)); // This include closing invoices
1572  if ($payment_id < 0)
1573  {
1574  $this->db->rollback();
1575  throw new RestException(400, 'Payment error : '.$paymentobj->error);
1576  }
1577  if (!empty($conf->banque->enabled)) {
1578  $label = '(CustomerInvoicePayment)';
1579  if ($paymentobj->paiementcode == 'CHQ' && empty($chqemetteur)) {
1580  throw new RestException(400, 'Emetteur is mandatory when payment code is '.$paymentobj->paiementcode);
1581  }
1582  if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) $label = '(CustomerInvoicePaymentBack)'; // Refund of a credit note
1583  $result = $paymentobj->addPaymentToBank(DolibarrApiAccess::$user, 'payment', $label, $accountid, $chqemetteur, $chqbank);
1584  if ($result < 0)
1585  {
1586  $this->db->rollback();
1587  throw new RestException(400, 'Add payment to bank error : '.$paymentobj->error);
1588  }
1589  }
1590 
1591  $this->db->commit();
1592 
1593  return $payment_id;
1594  }
1595 
1609  public function putPayment($id, $num_payment = '')
1610  {
1611  require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
1612 
1613  if (!DolibarrApiAccess::$user->rights->facture->creer) {
1614  throw new RestException(401);
1615  }
1616  if (empty($id)) {
1617  throw new RestException(400, 'Payment ID is mandatory');
1618  }
1619 
1620  $paymentobj = new Paiement($this->db);
1621  $result = $paymentobj->fetch($id);
1622 
1623  if (!$result) {
1624  throw new RestException(404, 'Payment not found');
1625  }
1626 
1627  if (!empty($num_payment)) {
1628  $result = $paymentobj->update_num($num_payment);
1629  if ($result < 0) {
1630  throw new RestException(500, 'Error when updating the payment num');
1631  }
1632  }
1633 
1634  return [
1635  'success' => [
1636  'code' => 200,
1637  'message' => 'Payment updated'
1638  ]
1639  ];
1640  }
1641 
1642  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1649  protected function _cleanObjectDatas($object)
1650  {
1651  // phpcs:enable
1652  $object = parent::_cleanObjectDatas($object);
1653 
1654  unset($object->note);
1655  unset($object->address);
1656  unset($object->barcode_type);
1657  unset($object->barcode_type_code);
1658  unset($object->barcode_type_label);
1659  unset($object->barcode_type_coder);
1660 
1661  return $object;
1662  }
1663 
1672  private function _validate($data)
1673  {
1674  $invoice = array();
1675  foreach (Invoices::$FIELDS as $field) {
1676  if (!isset($data[$field])) {
1677  throw new RestException(400, "$field field missing");
1678  }
1679  $invoice[$field] = $data[$field];
1680  }
1681  return $invoice;
1682  }
1683 }
const TYPE_STANDARD
Standard invoice.
getMarginInfos($pvht, $remise_percent, $tva_tx, $localtax1_tx, $localtax2_tx, $fk_pa, $paht)
Return an array with margins information of a line.
put($id, $request_data=null)
Update invoice.
useCreditNote($id, $discountid)
Add an available credit note discount to payments of an existing invoice.
settodraft($id, $idwarehouse=-1)
Sets an invoice as draft.
postLine($id, $request_data=null)
Add a line to a given invoice.
_validate($data)
Validate fields before create or update object.
getPayments($id)
Get list of payments of a given invoice.
addContact($id, $fk_socpeople, $type_contact, $source, $notrigger=0)
Adds a contact to an invoice.
dol_now($mode= 'auto')
Return date for now.
useDiscount($id, $discountid)
Add a discount line into an invoice (as an invoice line) using an existing absolute discount...
createInvoiceFromOrder($orderid)
Create an invoice using an existing order.
const TYPE_REPLACEMENT
Replacement invoice.
addPayment($id, $datepaye, $paymentid, $closepaidinvoices, $accountid, $num_payment= '', $comment= '', $chqemetteur= '', $chqbank= '')
Add payment line to a specific invoice with the remain to pay as amount.
settounpaid($id)
Sets an invoice as unpaid.
addPaymentDistributed($arrayofamounts, $datepaye, $paymentid, $closepaidinvoices, $accountid, $num_payment= '', $comment= '', $chqemetteur= '', $chqbank= '', $ref_ext= '', $accepthigherpayment=false)
Add a payment to pay partially or completely one or several invoices.
const TYPE_SITUATION
Situation invoice.
$conf db
API class for accounts.
Definition: inc.php:54
_checkFilters($sqlfilters)
Return if a $sqlfilters parameter is valid.
Definition: api.class.php:278
validate($id, $idwarehouse=0, $notrigger=0)
Validate an invoice.
const TYPE_CREDIT_NOTE
Credit note invoice.
__construct()
Constructor.
Class for API REST v1.
Definition: api.class.php:30
index($sortfield="t.rowid", $sortorder= 'ASC', $limit=100, $page=0, $thirdparty_ids= '', $status= '', $sqlfilters= '')
List invoices.
post($request_data=null)
Create invoice object.
price2num($amount, $rounding= '', $option=0)
Function that return a number with universal decimal format (decimal separator is &#39;...
Class to manage customers orders.
Class to manage payments of customer invoices.
deleteContact($id, $contactid, $type)
Delete a contact type of given invoice.
putLine($id, $lineid, $request_data=null)
Update a line to a given invoice.
settopaid($id, $close_code= '', $close_note= '')
Sets an invoice as paid.
markAsCreditAvailable($id)
Create a discount (credit available) for a credit note or a deposit.
postContact($id, $contactid, $type)
Add a contact type of given invoice.
getByRef($ref, $contact_list=1)
Get properties of an invoice object by ref.
_fetch($id, $ref= '', $ref_ext= '', $contact_list=1)
Get properties of an invoice object.
const TYPE_DEPOSIT
Deposit invoice.
static _checkAccessToResource($resource, $resource_id=0, $dbtablename= '', $feature2= '', $dbt_keyfield= 'fk_soc', $dbt_select= 'rowid')
Check user access to a resource.
Definition: api.class.php:252
dol_getIdFromCode($db, $key, $tablename, $fieldkey= 'code', $fieldid= 'id', $entityfilter=0)
Return an id or code from a code or id.
_cleanObjectDatas($object)
Clean sensible object datas.
if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if((!empty($conf->fournisseur->enabled)&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)||!empty($conf->supplier_invoice->enabled))&&$user->rights->fournisseur->facture->lire) if(!empty($conf->don->enabled)&&$user->rights->don->lire) if(!empty($conf->tax->enabled)&&$user->rights->tax->charges->lire) if(!empty($conf->facture->enabled)&&!empty($conf->commande->enabled)&&$user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if((!empty($conf->fournisseur->enabled)&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)||!empty($conf->supplier_invoice->enabled))&&$user->rights->fournisseur->facture->lire) $resql
Social contributions to pay.
Definition: index.php:1232
dol_print_error($db= '', $error= '', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
Class to manage absolute discounts.
getLines($id)
Get lines of an invoice.
Class to manage invoices.
deleteLine($id, $lineid)
Deletes a line of a given invoice.
putPayment($id, $num_payment= '')
Update a payment.
getDiscount($id)
Get discount from invoice.
getByRefExt($ref_ext, $contact_list=1)
Get properties of an invoice object by ref_ext.