dolibarr  x.y.z
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 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php';
23 
24 
31 class Invoices extends DolibarrApi
32 {
37  static $FIELDS = array(
38  'socid',
39  );
40 
44  private $invoice;
45 
49  private $template_invoice;
50 
51 
55  public function __construct()
56  {
57  global $db, $conf;
58  $this->db = $db;
59  $this->invoice = new Facture($this->db);
60  $this->template_invoice = new FactureRec($this->db);
61  }
62 
74  public function get($id, $contact_list = 1)
75  {
76  return $this->_fetch($id, '', '', $contact_list);
77  }
78 
92  public function getByRef($ref, $contact_list = 1)
93  {
94  return $this->_fetch('', $ref, '', $contact_list);
95  }
96 
110  public function getByRefExt($ref_ext, $contact_list = 1)
111  {
112  return $this->_fetch('', '', $ref_ext, $contact_list);
113  }
114 
128  private function _fetch($id, $ref = '', $ref_ext = '', $contact_list = 1)
129  {
130  if (!DolibarrApiAccess::$user->rights->facture->lire) {
131  throw new RestException(401);
132  }
133 
134  $result = $this->invoice->fetch($id, $ref, $ref_ext);
135  if (!$result) {
136  throw new RestException(404, 'Invoice not found');
137  }
138 
139  // Get payment details
140  $this->invoice->totalpaid = $this->invoice->getSommePaiement();
141  $this->invoice->totalcreditnotes = $this->invoice->getSumCreditNotesUsed();
142  $this->invoice->totaldeposits = $this->invoice->getSumDepositsUsed();
143  $this->invoice->remaintopay = price2num($this->invoice->total_ttc - $this->invoice->totalpaid - $this->invoice->totalcreditnotes - $this->invoice->totaldeposits, 'MT');
144 
145  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
146  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
147  }
148 
149  // Add external contacts ids
150  if ($contact_list > -1) {
151  $tmparray = $this->invoice->liste_contact(-1, 'external', $contact_list);
152  if (is_array($tmparray)) {
153  $this->invoice->contacts_ids = $tmparray;
154  }
155  }
156 
157  $this->invoice->fetchObjectLinked();
158 
159  return $this->_cleanObjectDatas($this->invoice);
160  }
161 
179  public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $status = '', $sqlfilters = '')
180  {
181  global $db, $conf;
182 
183  if (!DolibarrApiAccess::$user->rights->facture->lire) {
184  throw new RestException(401);
185  }
186 
187  $obj_ret = array();
188 
189  // case of external user, $thirdparty_ids param is ignored and replaced by user's socid
190  $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids;
191 
192  // If the internal user must only see his customers, force searching by him
193  $search_sale = 0;
194  if (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) {
195  $search_sale = DolibarrApiAccess::$user->id;
196  }
197 
198  $sql = "SELECT t.rowid";
199  if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) {
200  $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)
201  }
202  $sql .= " FROM ".MAIN_DB_PREFIX."facture as t";
203 
204  if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) {
205  $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale
206  }
207 
208  $sql .= ' WHERE t.entity IN ('.getEntity('invoice').')';
209  if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) {
210  $sql .= " AND t.fk_soc = sc.fk_soc";
211  }
212  if ($socids) {
213  $sql .= " AND t.fk_soc IN (".$this->db->sanitize($socids).")";
214  }
215 
216  if ($search_sale > 0) {
217  $sql .= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale
218  }
219 
220  // Filter by status
221  if ($status == 'draft') {
222  $sql .= " AND t.fk_statut IN (0)";
223  }
224  if ($status == 'unpaid') {
225  $sql .= " AND t.fk_statut IN (1)";
226  }
227  if ($status == 'paid') {
228  $sql .= " AND t.fk_statut IN (2)";
229  }
230  if ($status == 'cancelled') {
231  $sql .= " AND t.fk_statut IN (3)";
232  }
233  // Insert sale filter
234  if ($search_sale > 0) {
235  $sql .= " AND sc.fk_user = ".((int) $search_sale);
236  }
237  // Add sql filters
238  if ($sqlfilters) {
239  $errormessage = '';
240  if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
241  throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage);
242  }
243  $regexstring = '\‍(([^:\'\‍(\‍)]+:[^:\'\‍(\‍)]+:[^\‍(\‍)]+)\‍)';
244  $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
245  }
246 
247  $sql .= $this->db->order($sortfield, $sortorder);
248  if ($limit) {
249  if ($page < 0) {
250  $page = 0;
251  }
252  $offset = $limit * $page;
253 
254  $sql .= $this->db->plimit($limit + 1, $offset);
255  }
256 
257  $result = $this->db->query($sql);
258  if ($result) {
259  $i = 0;
260  $num = $this->db->num_rows($result);
261  $min = min($num, ($limit <= 0 ? $num : $limit));
262  while ($i < $min) {
263  $obj = $this->db->fetch_object($result);
264  $invoice_static = new Facture($this->db);
265  if ($invoice_static->fetch($obj->rowid)) {
266  // Get payment details
267  $invoice_static->totalpaid = $invoice_static->getSommePaiement();
268  $invoice_static->totalcreditnotes = $invoice_static->getSumCreditNotesUsed();
269  $invoice_static->totaldeposits = $invoice_static->getSumDepositsUsed();
270  $invoice_static->remaintopay = price2num($invoice_static->total_ttc - $invoice_static->totalpaid - $invoice_static->totalcreditnotes - $invoice_static->totaldeposits, 'MT');
271 
272  // Add external contacts ids
273  $tmparray = $invoice_static->liste_contact(-1, 'external', 1);
274  if (is_array($tmparray)) {
275  $invoice_static->contacts_ids = $tmparray;
276  }
277  $obj_ret[] = $this->_cleanObjectDatas($invoice_static);
278  }
279  $i++;
280  }
281  } else {
282  throw new RestException(503, 'Error when retrieve invoice list : '.$this->db->lasterror());
283  }
284  if (!count($obj_ret)) {
285  throw new RestException(404, 'No invoice found');
286  }
287  return $obj_ret;
288  }
289 
296  public function post($request_data = null)
297  {
298  if (!DolibarrApiAccess::$user->rights->facture->creer) {
299  throw new RestException(401, "Insuffisant rights");
300  }
301  // Check mandatory fields
302  $result = $this->_validate($request_data);
303 
304  foreach ($request_data as $field => $value) {
305  $this->invoice->$field = $value;
306  }
307  if (!array_key_exists('date', $request_data)) {
308  $this->invoice->date = dol_now();
309  }
310  /* We keep lines as an array
311  if (isset($request_data["lines"])) {
312  $lines = array();
313  foreach ($request_data["lines"] as $line) {
314  array_push($lines, (object) $line);
315  }
316  $this->invoice->lines = $lines;
317  }*/
318 
319  if ($this->invoice->create(DolibarrApiAccess::$user, 0, (empty($request_data["date_lim_reglement"]) ? 0 : $request_data["date_lim_reglement"])) < 0) {
320  throw new RestException(500, "Error creating invoice", array_merge(array($this->invoice->error), $this->invoice->errors));
321  }
322  return $this->invoice->id;
323  }
324 
338  public function createInvoiceFromOrder($orderid)
339  {
340  require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
341 
342  if (!DolibarrApiAccess::$user->rights->commande->lire) {
343  throw new RestException(401);
344  }
345  if (!DolibarrApiAccess::$user->rights->facture->creer) {
346  throw new RestException(401);
347  }
348  if (empty($orderid)) {
349  throw new RestException(400, 'Order ID is mandatory');
350  }
351 
352  $order = new Commande($this->db);
353  $result = $order->fetch($orderid);
354  if (!$result) {
355  throw new RestException(404, 'Order not found');
356  }
357 
358  $result = $this->invoice->createFromOrder($order, DolibarrApiAccess::$user);
359  if ($result < 0) {
360  throw new RestException(405, $this->invoice->error);
361  }
362  $this->invoice->fetchObjectLinked();
363  return $this->_cleanObjectDatas($this->invoice);
364  }
365 
374  public function getLines($id)
375  {
376  if (!DolibarrApiAccess::$user->rights->facture->lire) {
377  throw new RestException(401);
378  }
379 
380  $result = $this->invoice->fetch($id);
381  if (!$result) {
382  throw new RestException(404, 'Invoice not found');
383  }
384 
385  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
386  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
387  }
388  $this->invoice->getLinesArray();
389  $result = array();
390  foreach ($this->invoice->lines as $line) {
391  array_push($result, $this->_cleanObjectDatas($line));
392  }
393  return $result;
394  }
395 
410  public function putLine($id, $lineid, $request_data = null)
411  {
412  if (!DolibarrApiAccess::$user->rights->facture->creer) {
413  throw new RestException(401);
414  }
415 
416  $result = $this->invoice->fetch($id);
417  if (!$result) {
418  throw new RestException(404, 'Invoice not found');
419  }
420 
421  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
422  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
423  }
424 
425  $request_data = (object) $request_data;
426 
427  $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
428  $request_data->label = sanitizeVal($request_data->label);
429 
430  $updateRes = $this->invoice->updateline(
431  $lineid,
432  $request_data->desc,
433  $request_data->subprice,
434  $request_data->qty,
435  $request_data->remise_percent,
436  $request_data->date_start,
437  $request_data->date_end,
438  $request_data->tva_tx,
439  $request_data->localtax1_tx,
440  $request_data->localtax2_tx,
441  $request_data->price_base_type ? $request_data->price_base_type : 'HT',
442  $request_data->info_bits,
443  $request_data->product_type,
444  $request_data->fk_parent_line,
445  0,
446  $request_data->fk_fournprice,
447  $request_data->pa_ht,
448  $request_data->label,
449  $request_data->special_code,
450  $request_data->array_options,
451  $request_data->situation_percent,
452  $request_data->fk_unit,
453  $request_data->multicurrency_subprice,
454  0,
455  $request_data->ref_ext,
456  $request_data->rang
457  );
458 
459  if ($updateRes > 0) {
460  $result = $this->get($id);
461  unset($result->line);
462  return $this->_cleanObjectDatas($result);
463  } else {
464  throw new RestException(304, $this->invoice->error);
465  }
466  }
467 
481  public function postContact($id, $contactid, $type)
482  {
483  if (!DolibarrApiAccess::$user->rights->facture->creer) {
484  throw new RestException(401);
485  }
486 
487  $result = $this->invoice->fetch($id);
488 
489  if (!$result) {
490  throw new RestException(404, 'Invoice not found');
491  }
492 
493  if (!in_array($type, array('BILLING', 'SHIPPING', 'CUSTOMER'), true)) {
494  throw new RestException(500, 'Availables types: BILLING, SHIPPING OR CUSTOMER');
495  }
496 
497  if (!DolibarrApi::_checkAccessToResource('invoice', $this->invoice->id)) {
498  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
499  }
500 
501  $result = $this->invoice->add_contact($contactid, $type, 'external');
502 
503  if (!$result) {
504  throw new RestException(500, 'Error when added the contact');
505  }
506 
507  return array(
508  'success' => array(
509  'code' => 200,
510  'message' => 'Contact linked to the invoice'
511  )
512  );
513  }
514 
529  public function deleteContact($id, $contactid, $type)
530  {
531  if (!DolibarrApiAccess::$user->rights->facture->creer) {
532  throw new RestException(401);
533  }
534 
535  $result = $this->invoice->fetch($id);
536 
537  if (!$result) {
538  throw new RestException(404, 'Invoice not found');
539  }
540 
541  if (!DolibarrApi::_checkAccessToResource('invoice', $this->invoice->id)) {
542  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
543  }
544 
545  $contacts = $this->invoice->liste_contact();
546 
547  foreach ($contacts as $contact) {
548  if ($contact['id'] == $contactid && $contact['code'] == $type) {
549  $result = $this->invoice->delete_contact($contact['rowid']);
550 
551  if (!$result) {
552  throw new RestException(500, 'Error when deleted the contact');
553  }
554  }
555  }
556 
557  return $this->_cleanObjectDatas($this->invoice);
558  }
559 
574  public function deleteLine($id, $lineid)
575  {
576  if (!DolibarrApiAccess::$user->rights->facture->creer) {
577  throw new RestException(401);
578  }
579  if (empty($lineid)) {
580  throw new RestException(400, 'Line ID is mandatory');
581  }
582 
583  if (!DolibarrApi::_checkAccessToResource('facture', $id)) {
584  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
585  }
586 
587  $result = $this->invoice->fetch($id);
588  if (!$result) {
589  throw new RestException(404, 'Invoice not found');
590  }
591 
592  $updateRes = $this->invoice->deleteline($lineid, $id);
593  if ($updateRes > 0) {
594  return $this->get($id);
595  } else {
596  throw new RestException(405, $this->invoice->error);
597  }
598  }
599 
607  public function put($id, $request_data = null)
608  {
609  if (!DolibarrApiAccess::$user->rights->facture->creer) {
610  throw new RestException(401);
611  }
612 
613  $result = $this->invoice->fetch($id);
614  if (!$result) {
615  throw new RestException(404, 'Invoice not found');
616  }
617 
618  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
619  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
620  }
621 
622  foreach ($request_data as $field => $value) {
623  if ($field == 'id') {
624  continue;
625  }
626  $this->invoice->$field = $value;
627  }
628 
629  // update bank account
630  if (!empty($this->invoice->fk_account)) {
631  if ($this->invoice->setBankAccount($this->invoice->fk_account) == 0) {
632  throw new RestException(400, $this->invoice->error);
633  }
634  }
635 
636  if ($this->invoice->update(DolibarrApiAccess::$user)) {
637  return $this->get($id);
638  }
639 
640  return false;
641  }
642 
649  public function delete($id)
650  {
651  if (!DolibarrApiAccess::$user->rights->facture->supprimer) {
652  throw new RestException(401);
653  }
654  $result = $this->invoice->fetch($id);
655  if (!$result) {
656  throw new RestException(404, 'Invoice not found');
657  }
658 
659  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
660  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
661  }
662 
663  $result = $this->invoice->delete(DolibarrApiAccess::$user);
664  if ($result < 0) {
665  throw new RestException(500, 'Error when deleting invoice');
666  } elseif ($result == 0) {
667  throw new RestException(403, 'Invoice not erasable');
668  }
669 
670  return array(
671  'success' => array(
672  'code' => 200,
673  'message' => 'Invoice deleted'
674  )
675  );
676  }
677 
701  public function postLine($id, $request_data = null)
702  {
703  if (!DolibarrApiAccess::$user->rights->facture->creer) {
704  throw new RestException(401);
705  }
706 
707  $result = $this->invoice->fetch($id);
708  if (!$result) {
709  throw new RestException(404, 'Invoice not found');
710  }
711 
712  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
713  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
714  }
715 
716  $request_data = (object) $request_data;
717 
718  $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
719  $request_data->label = sanitizeVal($request_data->label);
720 
721  // Reset fk_parent_line for no child products and special product
722  if (($request_data->product_type != 9 && empty($request_data->fk_parent_line)) || $request_data->product_type == 9) {
723  $request_data->fk_parent_line = 0;
724  }
725 
726  // calculate pa_ht
727  $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);
728  $pa_ht = $marginInfos[0];
729 
730  $updateRes = $this->invoice->addline(
731  $request_data->desc,
732  $request_data->subprice,
733  $request_data->qty,
734  $request_data->tva_tx,
735  $request_data->localtax1_tx,
736  $request_data->localtax2_tx,
737  $request_data->fk_product,
738  $request_data->remise_percent,
739  $request_data->date_start,
740  $request_data->date_end,
741  $request_data->fk_code_ventilation,
742  $request_data->info_bits,
743  $request_data->fk_remise_except,
744  $request_data->price_base_type ? $request_data->price_base_type : 'HT',
745  $request_data->subprice,
746  $request_data->product_type,
747  $request_data->rang,
748  $request_data->special_code,
749  $request_data->origin,
750  $request_data->origin_id,
751  $request_data->fk_parent_line,
752  empty($request_data->fk_fournprice) ?null:$request_data->fk_fournprice,
753  $pa_ht,
754  $request_data->label,
755  $request_data->array_options,
756  $request_data->situation_percent,
757  $request_data->fk_prev_id,
758  $request_data->fk_unit,
759  0,
760  $request_data->ref_ext
761  );
762 
763  if ($updateRes < 0) {
764  throw new RestException(400, 'Unable to insert the new line. Check your inputs. '.$this->invoice->error);
765  }
766 
767  return $updateRes;
768  }
769 
789  public function addContact($id, $fk_socpeople, $type_contact, $source, $notrigger = 0)
790  {
791  if (!DolibarrApiAccess::$user->rights->facture->creer) {
792  throw new RestException(401);
793  }
794  $result = $this->invoice->fetch($id);
795  if (!$result) {
796  throw new RestException(404, 'Invoice not found');
797  }
798 
799  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
800  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
801  }
802 
803  $result = $this->invoice->add_contact($fk_socpeople, $type_contact, $source, $notrigger);
804  if ($result < 0) {
805  throw new RestException(500, 'Error : '.$this->invoice->error);
806  }
807 
808  $result = $this->invoice->fetch($id);
809  if (!$result) {
810  throw new RestException(404, 'Invoice not found');
811  }
812 
813  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
814  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
815  }
816 
817  return $this->_cleanObjectDatas($this->invoice);
818  }
819 
820 
821 
837  public function settodraft($id, $idwarehouse = -1)
838  {
839  if (!DolibarrApiAccess::$user->rights->facture->creer) {
840  throw new RestException(401);
841  }
842  $result = $this->invoice->fetch($id);
843  if (!$result) {
844  throw new RestException(404, 'Invoice not found');
845  }
846 
847  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
848  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
849  }
850 
851  $result = $this->invoice->setDraft(DolibarrApiAccess::$user, $idwarehouse);
852  if ($result == 0) {
853  throw new RestException(304, 'Nothing done.');
854  }
855  if ($result < 0) {
856  throw new RestException(500, 'Error : '.$this->invoice->error);
857  }
858 
859  $result = $this->invoice->fetch($id);
860  if (!$result) {
861  throw new RestException(404, 'Invoice not found');
862  }
863 
864  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
865  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
866  }
867 
868  return $this->_cleanObjectDatas($this->invoice);
869  }
870 
871 
888  public function validate($id, $idwarehouse = 0, $notrigger = 0)
889  {
890  if (!DolibarrApiAccess::$user->rights->facture->creer) {
891  throw new RestException(401);
892  }
893  $result = $this->invoice->fetch($id);
894  if (!$result) {
895  throw new RestException(404, 'Invoice not found');
896  }
897 
898  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
899  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
900  }
901 
902  $result = $this->invoice->validate(DolibarrApiAccess::$user, '', $idwarehouse, $notrigger);
903  if ($result == 0) {
904  throw new RestException(304, 'Error nothing done. May be object is already validated');
905  }
906  if ($result < 0) {
907  throw new RestException(500, 'Error when validating Invoice: '.$this->invoice->error);
908  }
909 
910  $result = $this->invoice->fetch($id);
911  if (!$result) {
912  throw new RestException(404, 'Invoice not found');
913  }
914 
915  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
916  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
917  }
918 
919  return $this->_cleanObjectDatas($this->invoice);
920  }
921 
937  public function settopaid($id, $close_code = '', $close_note = '')
938  {
939  if (!DolibarrApiAccess::$user->rights->facture->creer) {
940  throw new RestException(401);
941  }
942  $result = $this->invoice->fetch($id);
943  if (!$result) {
944  throw new RestException(404, 'Invoice not found');
945  }
946 
947  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
948  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
949  }
950 
951  $result = $this->invoice->setPaid(DolibarrApiAccess::$user, $close_code, $close_note);
952  if ($result == 0) {
953  throw new RestException(304, 'Error nothing done. May be object is already validated');
954  }
955  if ($result < 0) {
956  throw new RestException(500, 'Error : '.$this->invoice->error);
957  }
958 
959 
960  $result = $this->invoice->fetch($id);
961  if (!$result) {
962  throw new RestException(404, 'Invoice not found');
963  }
964 
965  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
966  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
967  }
968 
969  return $this->_cleanObjectDatas($this->invoice);
970  }
971 
972 
986  public function settounpaid($id)
987  {
988  if (!DolibarrApiAccess::$user->rights->facture->creer) {
989  throw new RestException(401);
990  }
991  $result = $this->invoice->fetch($id);
992  if (!$result) {
993  throw new RestException(404, 'Invoice not found');
994  }
995 
996  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
997  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
998  }
999 
1000  $result = $this->invoice->setUnpaid(DolibarrApiAccess::$user);
1001  if ($result == 0) {
1002  throw new RestException(304, 'Nothing done');
1003  }
1004  if ($result < 0) {
1005  throw new RestException(500, 'Error : '.$this->invoice->error);
1006  }
1007 
1008 
1009  $result = $this->invoice->fetch($id);
1010  if (!$result) {
1011  throw new RestException(404, 'Invoice not found');
1012  }
1013 
1014  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
1015  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1016  }
1017 
1018  return $this->_cleanObjectDatas($this->invoice);
1019  }
1020 
1029  public function getDiscount($id)
1030  {
1031  require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
1032 
1033  if (!DolibarrApiAccess::$user->rights->facture->lire) {
1034  throw new RestException(401);
1035  }
1036 
1037  $result = $this->invoice->fetch($id);
1038  if (!$result) {
1039  throw new RestException(404, 'Invoice not found');
1040  }
1041 
1042  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
1043  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1044  }
1045 
1046  $discountcheck = new DiscountAbsolute($this->db);
1047  $result = $discountcheck->fetch(0, $this->invoice->id);
1048 
1049  if ($result == 0) {
1050  throw new RestException(404, 'Discount not found');
1051  }
1052  if ($result < 0) {
1053  throw new RestException(500, $discountcheck->error);
1054  }
1055 
1056  return parent::_cleanObjectDatas($discountcheck);
1057  }
1058 
1072  public function markAsCreditAvailable($id)
1073  {
1074  require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
1075 
1076  if (!DolibarrApiAccess::$user->rights->facture->creer) {
1077  throw new RestException(401);
1078  }
1079 
1080  $result = $this->invoice->fetch($id);
1081  if (!$result) {
1082  throw new RestException(404, 'Invoice not found');
1083  }
1084 
1085  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
1086  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1087  }
1088 
1089  if ($this->invoice->paye) {
1090  throw new RestException(500, 'Alreay paid');
1091  }
1092 
1093  $this->invoice->fetch($id);
1094  $this->invoice->fetch_thirdparty();
1095 
1096  // Check if there is already a discount (protection to avoid duplicate creation when resubmit post)
1097  $discountcheck = new DiscountAbsolute($this->db);
1098  $result = $discountcheck->fetch(0, $this->invoice->id);
1099 
1100  $canconvert = 0;
1101  if ($this->invoice->type == Facture::TYPE_DEPOSIT && empty($discountcheck->id)) {
1102  $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)
1103  }
1104  if (($this->invoice->type == Facture::TYPE_CREDIT_NOTE || $this->invoice->type == Facture::TYPE_STANDARD) && $this->invoice->paye == 0 && empty($discountcheck->id)) {
1105  $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)
1106  }
1107  if ($canconvert) {
1108  $this->db->begin();
1109 
1110  $amount_ht = $amount_tva = $amount_ttc = array();
1111  $multicurrency_amount_ht = $multicurrency_amount_tva = $multicurrency_amount_ttc = array();
1112 
1113  // Loop on each vat rate
1114  $i = 0;
1115  foreach ($this->invoice->lines as $line) {
1116  if ($line->product_type < 9 && $line->total_ht != 0) { // Remove lines with product_type greater than or equal to 9
1117  // no need to create discount if amount is null
1118  $amount_ht[$line->tva_tx] += $line->total_ht;
1119  $amount_tva[$line->tva_tx] += $line->total_tva;
1120  $amount_ttc[$line->tva_tx] += $line->total_ttc;
1121  $multicurrency_amount_ht[$line->tva_tx] += $line->multicurrency_total_ht;
1122  $multicurrency_amount_tva[$line->tva_tx] += $line->multicurrency_total_tva;
1123  $multicurrency_amount_ttc[$line->tva_tx] += $line->multicurrency_total_ttc;
1124  $i++;
1125  }
1126  }
1127 
1128  // Insert one discount by VAT rate category
1129  $discount = new DiscountAbsolute($this->db);
1130  if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) {
1131  $discount->description = '(CREDIT_NOTE)';
1132  } elseif ($this->invoice->type == Facture::TYPE_DEPOSIT) {
1133  $discount->description = '(DEPOSIT)';
1134  } elseif ($this->invoice->type == Facture::TYPE_STANDARD || $this->invoice->type == Facture::TYPE_REPLACEMENT || $this->invoice->type == Facture::TYPE_SITUATION) {
1135  $discount->description = '(EXCESS RECEIVED)';
1136  } else {
1137  throw new RestException(500, 'Cant convert to reduc an Invoice of this type');
1138  }
1139 
1140  $discount->fk_soc = $this->invoice->socid;
1141  $discount->fk_facture_source = $this->invoice->id;
1142 
1143  $error = 0;
1144 
1145  if ($this->invoice->type == Facture::TYPE_STANDARD || $this->invoice->type == Facture::TYPE_REPLACEMENT || $this->invoice->type == Facture::TYPE_SITUATION) {
1146  // If we're on a standard invoice, we have to get excess received to create a discount in TTC without VAT
1147 
1148  // Total payments
1149  $sql = 'SELECT SUM(pf.amount) as total_payments';
1150  $sql .= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf, '.MAIN_DB_PREFIX.'paiement as p';
1151  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as c ON p.fk_paiement = c.id';
1152  $sql .= ' WHERE pf.fk_facture = '.((int) $this->invoice->id);
1153  $sql .= ' AND pf.fk_paiement = p.rowid';
1154  $sql .= ' AND p.entity IN ('.getEntity('invoice').')';
1155  $resql = $this->db->query($sql);
1156  if (!$resql) {
1157  dol_print_error($this->db);
1158  }
1159 
1160  $res = $this->db->fetch_object($resql);
1161  $total_payments = $res->total_payments;
1162 
1163  // Total credit note and deposit
1164  $total_creditnote_and_deposit = 0;
1165  $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,";
1166  $sql .= " re.description, re.fk_facture_source";
1167  $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re";
1168  $sql .= " WHERE fk_facture = ".((int) $this->invoice->id);
1169  $resql = $this->db->query($sql);
1170  if (!empty($resql)) {
1171  while ($obj = $this->db->fetch_object($resql)) {
1172  $total_creditnote_and_deposit += $obj->amount_ttc;
1173  }
1174  } else {
1175  dol_print_error($this->db);
1176  }
1177 
1178  $discount->amount_ht = $discount->amount_ttc = $total_payments + $total_creditnote_and_deposit - $this->invoice->total_ttc;
1179  $discount->amount_tva = 0;
1180  $discount->tva_tx = 0;
1181 
1182  $result = $discount->create(DolibarrApiAccess::$user);
1183  if ($result < 0) {
1184  $error++;
1185  }
1186  }
1187  if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE || $this->invoice->type == Facture::TYPE_DEPOSIT) {
1188  foreach ($amount_ht as $tva_tx => $xxx) {
1189  $discount->amount_ht = abs($amount_ht[$tva_tx]);
1190  $discount->amount_tva = abs($amount_tva[$tva_tx]);
1191  $discount->amount_ttc = abs($amount_ttc[$tva_tx]);
1192  $discount->multicurrency_amount_ht = abs($multicurrency_amount_ht[$tva_tx]);
1193  $discount->multicurrency_amount_tva = abs($multicurrency_amount_tva[$tva_tx]);
1194  $discount->multicurrency_amount_ttc = abs($multicurrency_amount_ttc[$tva_tx]);
1195  $discount->tva_tx = abs($tva_tx);
1196 
1197  $result = $discount->create(DolibarrApiAccess::$user);
1198  if ($result < 0) {
1199  $error++;
1200  break;
1201  }
1202  }
1203  }
1204 
1205  if (empty($error)) {
1206  if ($this->invoice->type != Facture::TYPE_DEPOSIT) {
1207  // Classe facture
1208  $result = $this->invoice->setPaid(DolibarrApiAccess::$user);
1209  if ($result >= 0) {
1210  $this->db->commit();
1211  } else {
1212  $this->db->rollback();
1213  throw new RestException(500, 'Could not set paid');
1214  }
1215  } else {
1216  $this->db->commit();
1217  }
1218  } else {
1219  $this->db->rollback();
1220  throw new RestException(500, 'Discount creation error');
1221  }
1222  }
1223 
1224  return $this->_cleanObjectDatas($this->invoice);
1225  }
1226 
1243  public function useDiscount($id, $discountid)
1244  {
1245  if (!DolibarrApiAccess::$user->rights->facture->creer) {
1246  throw new RestException(401);
1247  }
1248  if (empty($id)) {
1249  throw new RestException(400, 'Invoice ID is mandatory');
1250  }
1251  if (empty($discountid)) {
1252  throw new RestException(400, 'Discount ID is mandatory');
1253  }
1254 
1255  if (!DolibarrApi::_checkAccessToResource('facture', $id)) {
1256  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1257  }
1258 
1259  $result = $this->invoice->fetch($id);
1260  if (!$result) {
1261  throw new RestException(404, 'Invoice not found');
1262  }
1263 
1264  $result = $this->invoice->insert_discount($discountid);
1265  if ($result < 0) {
1266  throw new RestException(405, $this->invoice->error);
1267  }
1268 
1269  return $result;
1270  }
1271 
1288  public function useCreditNote($id, $discountid)
1289  {
1290  require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
1291 
1292  if (!DolibarrApiAccess::$user->rights->facture->creer) {
1293  throw new RestException(401);
1294  }
1295  if (empty($id)) {
1296  throw new RestException(400, 'Invoice ID is mandatory');
1297  }
1298  if (empty($discountid)) {
1299  throw new RestException(400, 'Credit ID is mandatory');
1300  }
1301 
1302  if (!DolibarrApi::_checkAccessToResource('facture', $id)) {
1303  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1304  }
1305  $discount = new DiscountAbsolute($this->db);
1306  $result = $discount->fetch($discountid);
1307  if (!$result) {
1308  throw new RestException(404, 'Credit not found');
1309  }
1310 
1311  $result = $discount->link_to_invoice(0, $id);
1312  if ($result < 0) {
1313  throw new RestException(405, $discount->error);
1314  }
1315 
1316  return $result;
1317  }
1318 
1332  public function getPayments($id)
1333  {
1334 
1335  if (!DolibarrApiAccess::$user->rights->facture->lire) {
1336  throw new RestException(401);
1337  }
1338  if (empty($id)) {
1339  throw new RestException(400, 'Invoice ID is mandatory');
1340  }
1341 
1342  if (!DolibarrApi::_checkAccessToResource('facture', $id)) {
1343  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1344  }
1345 
1346  $result = $this->invoice->fetch($id);
1347  if (!$result) {
1348  throw new RestException(404, 'Invoice not found');
1349  }
1350 
1351  $result = $this->invoice->getListOfPayments();
1352  if ($result < 0) {
1353  throw new RestException(405, $this->invoice->error);
1354  }
1355 
1356  return $result;
1357  }
1358 
1359 
1381  public function addPayment($id, $datepaye, $paymentid, $closepaidinvoices, $accountid, $num_payment = '', $comment = '', $chqemetteur = '', $chqbank = '')
1382  {
1383  require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
1384 
1385  if (!DolibarrApiAccess::$user->rights->facture->creer) {
1386  throw new RestException(403);
1387  }
1388  if (empty($id)) {
1389  throw new RestException(400, 'Invoice ID is mandatory');
1390  }
1391 
1392  if (!DolibarrApi::_checkAccessToResource('facture', $id)) {
1393  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1394  }
1395 
1396  if (isModEnabled("banque")) {
1397  if (empty($accountid)) {
1398  throw new RestException(400, 'Account ID is mandatory');
1399  }
1400  }
1401 
1402  if (empty($paymentid)) {
1403  throw new RestException(400, 'Payment ID or Payment Code is mandatory');
1404  }
1405 
1406 
1407  $result = $this->invoice->fetch($id);
1408  if (!$result) {
1409  throw new RestException(404, 'Invoice not found');
1410  }
1411 
1412  // Calculate amount to pay
1413  $totalpaid = $this->invoice->getSommePaiement();
1414  $totalcreditnotes = $this->invoice->getSumCreditNotesUsed();
1415  $totaldeposits = $this->invoice->getSumDepositsUsed();
1416  $resteapayer = price2num($this->invoice->total_ttc - $totalpaid - $totalcreditnotes - $totaldeposits, 'MT');
1417 
1418  $this->db->begin();
1419 
1420  $amounts = array();
1421  $multicurrency_amounts = array();
1422 
1423  // Clean parameters amount if payment is for a credit note
1424  if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) {
1425  $resteapayer = price2num($resteapayer, 'MT');
1426  $amounts[$id] = -$resteapayer;
1427  // Multicurrency
1428  $newvalue = price2num($this->invoice->multicurrency_total_ttc, 'MT');
1429  $multicurrency_amounts[$id] = -$newvalue;
1430  } else {
1431  $resteapayer = price2num($resteapayer, 'MT');
1432  $amounts[$id] = $resteapayer;
1433  // Multicurrency
1434  $newvalue = price2num($this->invoice->multicurrency_total_ttc, 'MT');
1435  $multicurrency_amounts[$id] = $newvalue;
1436  }
1437 
1438  // Creation of payment line
1439  $paymentobj = new Paiement($this->db);
1440  $paymentobj->datepaye = $datepaye;
1441  $paymentobj->amounts = $amounts; // Array with all payments dispatching with invoice id
1442  $paymentobj->multicurrency_amounts = $multicurrency_amounts; // Array with all payments dispatching
1443  $paymentobj->paiementid = $paymentid;
1444  $paymentobj->paiementcode = dol_getIdFromCode($this->db, $paymentid, 'c_paiement', 'id', 'code', 1);
1445  $paymentobj->num_payment = $num_payment;
1446  $paymentobj->note_private = $comment;
1447 
1448  $payment_id = $paymentobj->create(DolibarrApiAccess::$user, ($closepaidinvoices == 'yes' ? 1 : 0)); // This include closing invoices
1449  if ($payment_id < 0) {
1450  $this->db->rollback();
1451  throw new RestException(400, 'Payment error : '.$paymentobj->error);
1452  }
1453 
1454  if (isModEnabled("banque")) {
1455  $label = '(CustomerInvoicePayment)';
1456 
1457  if ($paymentobj->paiementcode == 'CHQ' && empty($chqemetteur)) {
1458  throw new RestException(400, 'Emetteur is mandatory when payment code is '.$paymentobj->paiementcode);
1459  }
1460  if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) {
1461  $label = '(CustomerInvoicePaymentBack)'; // Refund of a credit note
1462  }
1463  $result = $paymentobj->addPaymentToBank(DolibarrApiAccess::$user, 'payment', $label, $accountid, $chqemetteur, $chqbank);
1464  if ($result < 0) {
1465  $this->db->rollback();
1466  throw new RestException(400, 'Add payment to bank error : '.$paymentobj->error);
1467  }
1468  }
1469 
1470  $this->db->commit();
1471 
1472  return $payment_id;
1473  }
1474 
1501  public function addPaymentDistributed($arrayofamounts, $datepaye, $paymentid, $closepaidinvoices, $accountid, $num_payment = '', $comment = '', $chqemetteur = '', $chqbank = '', $ref_ext = '', $accepthigherpayment = false)
1502  {
1503  require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
1504 
1505  if (!DolibarrApiAccess::$user->rights->facture->creer) {
1506  throw new RestException(403);
1507  }
1508  foreach ($arrayofamounts as $id => $amount) {
1509  if (empty($id)) {
1510  throw new RestException(400, 'Invoice ID is mandatory. Fill the invoice id and amount into arrayofamounts parameter. For example: {"1": "99.99", "2": "10"}');
1511  }
1512  if (!DolibarrApi::_checkAccessToResource('facture', $id)) {
1513  throw new RestException(403, 'Access not allowed on invoice ID '.$id.' for login '.DolibarrApiAccess::$user->login);
1514  }
1515  }
1516 
1517  if (isModEnabled("banque")) {
1518  if (empty($accountid)) {
1519  throw new RestException(400, 'Account ID is mandatory');
1520  }
1521  }
1522  if (empty($paymentid)) {
1523  throw new RestException(400, 'Payment ID or Payment Code is mandatory');
1524  }
1525 
1526  $this->db->begin();
1527 
1528  $amounts = array();
1529  $multicurrency_amounts = array();
1530 
1531  // Loop on each invoice to pay
1532  foreach ($arrayofamounts as $id => $amountarray) {
1533  $result = $this->invoice->fetch($id);
1534  if (!$result) {
1535  $this->db->rollback();
1536  throw new RestException(404, 'Invoice ID '.$id.' not found');
1537  }
1538 
1539  if (($amountarray["amount"] == "remain" || $amountarray["amount"] > 0) && ($amountarray["multicurrency_amount"] == "remain" || $amountarray["multicurrency_amount"] > 0)) {
1540  $this->db->rollback();
1541  throw new RestException(400, 'Payment in both currency '.$id.' ( amount: '.$amountarray["amount"].', multicurrency_amount: '.$amountarray["multicurrency_amount"].')');
1542  }
1543 
1544  $is_multicurrency = 0;
1545  $total_ttc = $this->invoice->total_ttc;
1546 
1547  if ($amountarray["multicurrency_amount"] > 0 || $amountarray["multicurrency_amount"] == "remain") {
1548  $is_multicurrency = 1;
1549  $total_ttc = $this->invoice->multicurrency_total_ttc;
1550  }
1551 
1552  // Calculate amount to pay
1553  $totalpaid = $this->invoice->getSommePaiement($is_multicurrency);
1554  $totalcreditnotes = $this->invoice->getSumCreditNotesUsed($is_multicurrency);
1555  $totaldeposits = $this->invoice->getSumDepositsUsed($is_multicurrency);
1556  $remainstopay = $amount = price2num($total_ttc - $totalpaid - $totalcreditnotes - $totaldeposits, 'MT');
1557 
1558  if (!$is_multicurrency && $amountarray["amount"] != 'remain') {
1559  $amount = price2num($amountarray["amount"], 'MT');
1560  }
1561 
1562  if ($is_multicurrency && $amountarray["multicurrency_amount"] != 'remain') {
1563  $amount = price2num($amountarray["multicurrency_amount"], 'MT');
1564  }
1565 
1566  if ($amount > $remainstopay && !$accepthigherpayment) {
1567  $this->db->rollback();
1568  throw new RestException(400, 'Payment amount on invoice ID '.$id.' ('.$amount.') is higher than remain to pay ('.$remainstopay.')');
1569  }
1570 
1571  if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) {
1572  $amount = -$amount;
1573  }
1574 
1575  if ($is_multicurrency) {
1576  $amounts[$id] = null;
1577  // Multicurrency
1578  $multicurrency_amounts[$id] = $amount;
1579  } else {
1580  $amounts[$id] = $amount;
1581  // Multicurrency
1582  $multicurrency_amounts[$id] = null;
1583  }
1584  }
1585 
1586  // Creation of payment line
1587  $paymentobj = new Paiement($this->db);
1588  $paymentobj->datepaye = $datepaye;
1589  $paymentobj->amounts = $amounts; // Array with all payments dispatching with invoice id
1590  $paymentobj->multicurrency_amounts = $multicurrency_amounts; // Array with all payments dispatching
1591  $paymentobj->paiementid = $paymentid;
1592  $paymentobj->paiementcode = dol_getIdFromCode($this->db, $paymentid, 'c_paiement', 'id', 'code', 1);
1593  $paymentobj->num_payment = $num_payment;
1594  $paymentobj->note_private = $comment;
1595  $paymentobj->ref_ext = $ref_ext;
1596  $payment_id = $paymentobj->create(DolibarrApiAccess::$user, ($closepaidinvoices == 'yes' ? 1 : 0)); // This include closing invoices
1597  if ($payment_id < 0) {
1598  $this->db->rollback();
1599  throw new RestException(400, 'Payment error : '.$paymentobj->error);
1600  }
1601  if (isModEnabled("banque")) {
1602  $label = '(CustomerInvoicePayment)';
1603  if ($paymentobj->paiementcode == 'CHQ' && empty($chqemetteur)) {
1604  throw new RestException(400, 'Emetteur is mandatory when payment code is '.$paymentobj->paiementcode);
1605  }
1606  if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) {
1607  $label = '(CustomerInvoicePaymentBack)'; // Refund of a credit note
1608  }
1609  $result = $paymentobj->addPaymentToBank(DolibarrApiAccess::$user, 'payment', $label, $accountid, $chqemetteur, $chqbank);
1610  if ($result < 0) {
1611  $this->db->rollback();
1612  throw new RestException(400, 'Add payment to bank error : '.$paymentobj->error);
1613  }
1614  }
1615 
1616  $this->db->commit();
1617 
1618  return $payment_id;
1619  }
1620 
1635  public function putPayment($id, $num_payment = '')
1636  {
1637  require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
1638 
1639  if (!DolibarrApiAccess::$user->rights->facture->creer) {
1640  throw new RestException(401);
1641  }
1642  if (empty($id)) {
1643  throw new RestException(400, 'Payment ID is mandatory');
1644  }
1645 
1646  $paymentobj = new Paiement($this->db);
1647  $result = $paymentobj->fetch($id);
1648 
1649  if (!$result) {
1650  throw new RestException(404, 'Payment not found');
1651  }
1652 
1653  if (!empty($num_payment)) {
1654  $result = $paymentobj->update_num($num_payment);
1655  if ($result < 0) {
1656  throw new RestException(500, 'Error when updating the payment num');
1657  }
1658  }
1659 
1660  return [
1661  'success' => [
1662  'code' => 200,
1663  'message' => 'Payment updated'
1664  ]
1665  ];
1666  }
1667 
1668  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1675  protected function _cleanObjectDatas($object)
1676  {
1677  // phpcs:enable
1678  $object = parent::_cleanObjectDatas($object);
1679 
1680  unset($object->note);
1681  unset($object->address);
1682  unset($object->barcode_type);
1683  unset($object->barcode_type_code);
1684  unset($object->barcode_type_label);
1685  unset($object->barcode_type_coder);
1686  unset($object->canvas);
1687 
1688  return $object;
1689  }
1690 
1699  private function _validate($data)
1700  {
1701  $invoice = array();
1702  foreach (Invoices::$FIELDS as $field) {
1703  if (!isset($data[$field])) {
1704  throw new RestException(400, "$field field missing");
1705  }
1706  $invoice[$field] = $data[$field];
1707  }
1708  return $invoice;
1709  }
1710 
1711 
1725  public function getTemplateInvoice($id, $contact_list = 1)
1726  {
1727  return $this->_fetchTemplateInvoice($id, '', '', $contact_list);
1728  }
1729 
1743  private function _fetchTemplateInvoice($id, $ref = '', $ref_ext = '', $contact_list = 1)
1744  {
1745  if (!DolibarrApiAccess::$user->rights->facture->lire) {
1746  throw new RestException(401);
1747  }
1748 
1749  $result = $this->template_invoice->fetch($id, $ref, $ref_ext);
1750  if (!$result) {
1751  throw new RestException(404, 'Template invoice not found');
1752  }
1753 
1754  if (!DolibarrApi::_checkAccessToResource('facturerec', $this->template_invoice->id)) {
1755  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1756  }
1757 
1758  // Add external contacts ids
1759  if ($contact_list > -1) {
1760  $tmparray = $this->template_invoice->liste_contact(-1, 'external', $contact_list);
1761  if (is_array($tmparray)) {
1762  $this->template_invoice->contacts_ids = $tmparray;
1763  }
1764  }
1765 
1766  $this->template_invoice->fetchObjectLinked();
1767  return $this->_cleanTemplateObjectDatas($this->template_invoice);
1768  }
1769 
1770 
1771  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1778  protected function _cleanTemplateObjectDatas($object)
1779  {
1780  // phpcs:enable
1781  $object = parent::_cleanObjectDatas($object);
1782 
1783  unset($object->note);
1784  unset($object->address);
1785  unset($object->barcode_type);
1786  unset($object->barcode_type_code);
1787  unset($object->barcode_type_label);
1788  unset($object->barcode_type_coder);
1789  unset($object->canvas);
1790 
1791  return $object;
1792  }
1793 }
Class to manage customers orders.
Class to manage absolute discounts.
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
_checkFilters($sqlfilters, &$error='')
Return if a $sqlfilters parameter is valid.
Definition: api.class.php:310
Class to manage invoices.
const TYPE_REPLACEMENT
Replacement invoice.
const TYPE_STANDARD
Standard invoice.
const TYPE_SITUATION
Situation invoice.
const TYPE_DEPOSIT
Deposit invoice.
const TYPE_CREDIT_NOTE
Credit note invoice.
Class to manage invoice templates.
postContact($id, $contactid, $type)
Add a contact type of given invoice.
putPayment($id, $num_payment='')
Update a payment.
addContact($id, $fk_socpeople, $type_contact, $source, $notrigger=0)
Adds a contact to an invoice.
createInvoiceFromOrder($orderid)
Create an invoice using an existing order.
markAsCreditAvailable($id)
Create a discount (credit available) for a credit note or a deposit.
getDiscount($id)
Get discount from invoice.
__construct()
Constructor.
put($id, $request_data=null)
Update invoice.
getByRefExt($ref_ext, $contact_list=1)
Get properties of an invoice object by ref_ext.
_fetch($id, $ref='', $ref_ext='', $contact_list=1)
Get properties of an invoice object.
getByRef($ref, $contact_list=1)
Get properties of an invoice object by ref.
getPayments($id)
Get list of payments of a given invoice.
_cleanObjectDatas($object)
Clean sensible object datas.
post($request_data=null)
Create invoice object.
useDiscount($id, $discountid)
Add a discount line into an invoice (as an invoice line) using an existing absolute discount.
settounpaid($id)
Sets an invoice as unpaid.
getTemplateInvoice($id, $contact_list=1)
Get properties of a template invoice object.
putLine($id, $lineid, $request_data=null)
Update a line to a given invoice.
getLines($id)
Get lines of an invoice.
index($sortfield="t.rowid", $sortorder='ASC', $limit=100, $page=0, $thirdparty_ids='', $status='', $sqlfilters='')
List invoices.
useCreditNote($id, $discountid)
Add an available credit note discount to payments of an existing invoice.
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.
validate($id, $idwarehouse=0, $notrigger=0)
Validate an invoice.
_cleanTemplateObjectDatas($object)
Clean sensible object datas.
deleteContact($id, $contactid, $type)
Delete a contact type of given invoice.
postLine($id, $request_data=null)
Add a line to a given invoice.
_fetchTemplateInvoice($id, $ref='', $ref_ext='', $contact_list=1)
Get properties of an invoice object.
_validate($data)
Validate fields before create or update object.
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.
settopaid($id, $close_code='', $close_note='')
Sets an invoice as paid.
settodraft($id, $idwarehouse=-1)
Sets an invoice as draft.
deleteLine($id, $lineid)
Deletes a line of a given invoice.
Class to manage payments of customer invoices.
if(isModEnabled('facture') &&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') &&!empty($user->rights->don->lire)) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:745
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
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.
getMarginInfos($pvht, $remise_percent, $tva_tx, $localtax1_tx, $localtax2_tx, $fk_pa, $paht)
Return an array with margins information of a line.
$conf db
API class for accounts.
Definition: inc.php:41