dolibarr  16.0.5
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 
339  public function createInvoiceFromOrder($orderid)
340  {
341 
342  require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
343 
344  if (!DolibarrApiAccess::$user->rights->commande->lire) {
345  throw new RestException(401);
346  }
347  if (!DolibarrApiAccess::$user->rights->facture->creer) {
348  throw new RestException(401);
349  }
350  if (empty($orderid)) {
351  throw new RestException(400, 'Order ID is mandatory');
352  }
353 
354  $order = new Commande($this->db);
355  $result = $order->fetch($orderid);
356  if (!$result) {
357  throw new RestException(404, 'Order not found');
358  }
359 
360  $result = $this->invoice->createFromOrder($order, DolibarrApiAccess::$user);
361  if ($result < 0) {
362  throw new RestException(405, $this->invoice->error);
363  }
364  $this->invoice->fetchObjectLinked();
365  return $this->_cleanObjectDatas($this->invoice);
366  }
367 
377  public function getLines($id)
378  {
379  if (!DolibarrApiAccess::$user->rights->facture->lire) {
380  throw new RestException(401);
381  }
382 
383  $result = $this->invoice->fetch($id);
384  if (!$result) {
385  throw new RestException(404, 'Invoice not found');
386  }
387 
388  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
389  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
390  }
391  $this->invoice->getLinesArray();
392  $result = array();
393  foreach ($this->invoice->lines as $line) {
394  array_push($result, $this->_cleanObjectDatas($line));
395  }
396  return $result;
397  }
398 
414  public function putLine($id, $lineid, $request_data = null)
415  {
416  if (!DolibarrApiAccess::$user->rights->facture->creer) {
417  throw new RestException(401);
418  }
419 
420  $result = $this->invoice->fetch($id);
421  if (!$result) {
422  throw new RestException(404, 'Invoice not found');
423  }
424 
425  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
426  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
427  }
428 
429  $request_data = (object) $request_data;
430 
431  $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
432  $request_data->label = sanitizeVal($request_data->label);
433 
434  $updateRes = $this->invoice->updateline(
435  $lineid,
436  $request_data->desc,
437  $request_data->subprice,
438  $request_data->qty,
439  $request_data->remise_percent,
440  $request_data->date_start,
441  $request_data->date_end,
442  $request_data->tva_tx,
443  $request_data->localtax1_tx,
444  $request_data->localtax2_tx,
445  $request_data->price_base_type ? $request_data->price_base_type : 'HT',
446  $request_data->info_bits,
447  $request_data->product_type,
448  $request_data->fk_parent_line,
449  0,
450  $request_data->fk_fournprice,
451  $request_data->pa_ht,
452  $request_data->label,
453  $request_data->special_code,
454  $request_data->array_options,
455  $request_data->situation_percent,
456  $request_data->fk_unit,
457  $request_data->multicurrency_subprice,
458  0,
459  $request_data->ref_ext,
460  $request_data->rang
461  );
462 
463  if ($updateRes > 0) {
464  $result = $this->get($id);
465  unset($result->line);
466  return $this->_cleanObjectDatas($result);
467  } else {
468  throw new RestException(304, $this->invoice->error);
469  }
470  }
471 
486  public function postContact($id, $contactid, $type)
487  {
488  if (!DolibarrApiAccess::$user->rights->facture->creer) {
489  throw new RestException(401);
490  }
491 
492  $result = $this->invoice->fetch($id);
493 
494  if (!$result) {
495  throw new RestException(404, 'Invoice not found');
496  }
497 
498  if (!in_array($type, array('BILLING', 'SHIPPING', 'CUSTOMER'), true)) {
499  throw new RestException(500, 'Availables types: BILLING, SHIPPING OR CUSTOMER');
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  $result = $this->invoice->add_contact($contactid, $type, 'external');
507 
508  if (!$result) {
509  throw new RestException(500, 'Error when added the contact');
510  }
511 
512  return $this->_cleanObjectDatas($this->invoice);
513  }
514 
530  public function deleteContact($id, $contactid, $type)
531  {
532  if (!DolibarrApiAccess::$user->rights->facture->creer) {
533  throw new RestException(401);
534  }
535 
536  $result = $this->invoice->fetch($id);
537 
538  if (!$result) {
539  throw new RestException(404, 'Invoice not found');
540  }
541 
542  if (!DolibarrApi::_checkAccessToResource('invoice', $this->invoice->id)) {
543  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
544  }
545 
546  $contacts = $this->invoice->liste_contact();
547 
548  foreach ($contacts as $contact) {
549  if ($contact['id'] == $contactid && $contact['code'] == $type) {
550  $result = $this->invoice->delete_contact($contact['rowid']);
551 
552  if (!$result) {
553  throw new RestException(500, 'Error when deleted the contact');
554  }
555  }
556  }
557 
558  return $this->_cleanObjectDatas($this->invoice);
559  }
560 
576  public function deleteLine($id, $lineid)
577  {
578 
579  if (!DolibarrApiAccess::$user->rights->facture->creer) {
580  throw new RestException(401);
581  }
582  if (empty($lineid)) {
583  throw new RestException(400, 'Line ID is mandatory');
584  }
585 
586  if (!DolibarrApi::_checkAccessToResource('facture', $id)) {
587  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
588  }
589 
590  $result = $this->invoice->fetch($id);
591  if (!$result) {
592  throw new RestException(404, 'Invoice not found');
593  }
594 
595  // TODO Check the lineid $lineid is a line of ojbect
596 
597  $updateRes = $this->invoice->deleteline($lineid);
598  if ($updateRes > 0) {
599  return $this->get($id);
600  } else {
601  throw new RestException(405, $this->invoice->error);
602  }
603  }
604 
612  public function put($id, $request_data = null)
613  {
614  if (!DolibarrApiAccess::$user->rights->facture->creer) {
615  throw new RestException(401);
616  }
617 
618  $result = $this->invoice->fetch($id);
619  if (!$result) {
620  throw new RestException(404, 'Invoice not found');
621  }
622 
623  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
624  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
625  }
626 
627  foreach ($request_data as $field => $value) {
628  if ($field == 'id') {
629  continue;
630  }
631  $this->invoice->$field = $value;
632  }
633 
634  // update bank account
635  if (!empty($this->invoice->fk_account)) {
636  if ($this->invoice->setBankAccount($this->invoice->fk_account) == 0) {
637  throw new RestException(400, $this->invoice->error);
638  }
639  }
640 
641  if ($this->invoice->update(DolibarrApiAccess::$user)) {
642  return $this->get($id);
643  }
644 
645  return false;
646  }
647 
654  public function delete($id)
655  {
656  if (!DolibarrApiAccess::$user->rights->facture->supprimer) {
657  throw new RestException(401);
658  }
659  $result = $this->invoice->fetch($id);
660  if (!$result) {
661  throw new RestException(404, 'Invoice not found');
662  }
663 
664  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
665  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
666  }
667 
668  $result = $this->invoice->delete(DolibarrApiAccess::$user);
669  if ($result < 0) {
670  throw new RestException(500, 'Error when deleting invoice');
671  }
672 
673  return array(
674  'success' => array(
675  'code' => 200,
676  'message' => 'Invoice deleted'
677  )
678  );
679  }
680 
704  public function postLine($id, $request_data = null)
705  {
706  if (!DolibarrApiAccess::$user->rights->facture->creer) {
707  throw new RestException(401);
708  }
709 
710  $result = $this->invoice->fetch($id);
711  if (!$result) {
712  throw new RestException(404, 'Invoice not found');
713  }
714 
715  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
716  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
717  }
718 
719  $request_data = (object) $request_data;
720 
721  $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
722  $request_data->label = sanitizeVal($request_data->label);
723 
724  // Reset fk_parent_line for no child products and special product
725  if (($request_data->product_type != 9 && empty($request_data->fk_parent_line)) || $request_data->product_type == 9) {
726  $request_data->fk_parent_line = 0;
727  }
728 
729  // calculate pa_ht
730  $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);
731  $pa_ht = $marginInfos[0];
732 
733  $updateRes = $this->invoice->addline(
734  $request_data->desc,
735  $request_data->subprice,
736  $request_data->qty,
737  $request_data->tva_tx,
738  $request_data->localtax1_tx,
739  $request_data->localtax2_tx,
740  $request_data->fk_product,
741  $request_data->remise_percent,
742  $request_data->date_start,
743  $request_data->date_end,
744  $request_data->fk_code_ventilation,
745  $request_data->info_bits,
746  $request_data->fk_remise_except,
747  $request_data->price_base_type ? $request_data->price_base_type : 'HT',
748  $request_data->subprice,
749  $request_data->product_type,
750  $request_data->rang,
751  $request_data->special_code,
752  $request_data->origin,
753  $request_data->origin_id,
754  $request_data->fk_parent_line,
755  empty($request_data->fk_fournprice) ?null:$request_data->fk_fournprice,
756  $pa_ht,
757  $request_data->label,
758  $request_data->array_options,
759  $request_data->situation_percent,
760  $request_data->fk_prev_id,
761  $request_data->fk_unit,
762  0,
763  $request_data->ref_ext
764  );
765 
766  if ($updateRes < 0) {
767  throw new RestException(400, 'Unable to insert the new line. Check your inputs. '.$this->invoice->error);
768  }
769 
770  return $updateRes;
771  }
772 
792  public function addContact($id, $fk_socpeople, $type_contact, $source, $notrigger = 0)
793  {
794  if (!DolibarrApiAccess::$user->rights->facture->creer) {
795  throw new RestException(401);
796  }
797  $result = $this->invoice->fetch($id);
798  if (!$result) {
799  throw new RestException(404, 'Invoice not found');
800  }
801 
802  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
803  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
804  }
805 
806  $result = $this->invoice->add_contact($fk_socpeople, $type_contact, $source, $notrigger);
807  if ($result < 0) {
808  throw new RestException(500, 'Error : '.$this->invoice->error);
809  }
810 
811  $result = $this->invoice->fetch($id);
812  if (!$result) {
813  throw new RestException(404, 'Invoice not found');
814  }
815 
816  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
817  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
818  }
819 
820  return $this->_cleanObjectDatas($this->invoice);
821  }
822 
823 
824 
841  public function settodraft($id, $idwarehouse = -1)
842  {
843  if (!DolibarrApiAccess::$user->rights->facture->creer) {
844  throw new RestException(401);
845  }
846  $result = $this->invoice->fetch($id);
847  if (!$result) {
848  throw new RestException(404, 'Invoice not found');
849  }
850 
851  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
852  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
853  }
854 
855  $result = $this->invoice->setDraft(DolibarrApiAccess::$user, $idwarehouse);
856  if ($result == 0) {
857  throw new RestException(304, 'Nothing done.');
858  }
859  if ($result < 0) {
860  throw new RestException(500, 'Error : '.$this->invoice->error);
861  }
862 
863  $result = $this->invoice->fetch($id);
864  if (!$result) {
865  throw new RestException(404, 'Invoice not found');
866  }
867 
868  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
869  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
870  }
871 
872  return $this->_cleanObjectDatas($this->invoice);
873  }
874 
875 
893  public function validate($id, $idwarehouse = 0, $notrigger = 0)
894  {
895  if (!DolibarrApiAccess::$user->rights->facture->creer) {
896  throw new RestException(401);
897  }
898  $result = $this->invoice->fetch($id);
899  if (!$result) {
900  throw new RestException(404, 'Invoice not found');
901  }
902 
903  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
904  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
905  }
906 
907  $result = $this->invoice->validate(DolibarrApiAccess::$user, '', $idwarehouse, $notrigger);
908  if ($result == 0) {
909  throw new RestException(304, 'Error nothing done. May be object is already validated');
910  }
911  if ($result < 0) {
912  throw new RestException(500, 'Error when validating Invoice: '.$this->invoice->error);
913  }
914 
915  $result = $this->invoice->fetch($id);
916  if (!$result) {
917  throw new RestException(404, 'Invoice not found');
918  }
919 
920  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
921  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
922  }
923 
924  return $this->_cleanObjectDatas($this->invoice);
925  }
926 
943  public function settopaid($id, $close_code = '', $close_note = '')
944  {
945  if (!DolibarrApiAccess::$user->rights->facture->creer) {
946  throw new RestException(401);
947  }
948  $result = $this->invoice->fetch($id);
949  if (!$result) {
950  throw new RestException(404, 'Invoice not found');
951  }
952 
953  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
954  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
955  }
956 
957  $result = $this->invoice->setPaid(DolibarrApiAccess::$user, $close_code, $close_note);
958  if ($result == 0) {
959  throw new RestException(304, 'Error nothing done. May be object is already validated');
960  }
961  if ($result < 0) {
962  throw new RestException(500, 'Error : '.$this->invoice->error);
963  }
964 
965 
966  $result = $this->invoice->fetch($id);
967  if (!$result) {
968  throw new RestException(404, 'Invoice not found');
969  }
970 
971  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
972  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
973  }
974 
975  return $this->_cleanObjectDatas($this->invoice);
976  }
977 
978 
993  public function settounpaid($id)
994  {
995  if (!DolibarrApiAccess::$user->rights->facture->creer) {
996  throw new RestException(401);
997  }
998  $result = $this->invoice->fetch($id);
999  if (!$result) {
1000  throw new RestException(404, 'Invoice not found');
1001  }
1002 
1003  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
1004  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1005  }
1006 
1007  $result = $this->invoice->setUnpaid(DolibarrApiAccess::$user);
1008  if ($result == 0) {
1009  throw new RestException(304, 'Nothing done');
1010  }
1011  if ($result < 0) {
1012  throw new RestException(500, 'Error : '.$this->invoice->error);
1013  }
1014 
1015 
1016  $result = $this->invoice->fetch($id);
1017  if (!$result) {
1018  throw new RestException(404, 'Invoice not found');
1019  }
1020 
1021  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
1022  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1023  }
1024 
1025  return $this->_cleanObjectDatas($this->invoice);
1026  }
1027 
1037  public function getDiscount($id)
1038  {
1039  require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
1040 
1041  if (!DolibarrApiAccess::$user->rights->facture->lire) {
1042  throw new RestException(401);
1043  }
1044 
1045  $result = $this->invoice->fetch($id);
1046  if (!$result) {
1047  throw new RestException(404, 'Invoice not found');
1048  }
1049 
1050  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
1051  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1052  }
1053 
1054  $discountcheck = new DiscountAbsolute($this->db);
1055  $result = $discountcheck->fetch(0, $this->invoice->id);
1056 
1057  if ($result == 0) {
1058  throw new RestException(404, 'Discount not found');
1059  }
1060  if ($result < 0) {
1061  throw new RestException(500, $discountcheck->error);
1062  }
1063 
1064  return parent::_cleanObjectDatas($discountcheck);
1065  }
1066 
1080  public function markAsCreditAvailable($id)
1081  {
1082  require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
1083 
1084  if (!DolibarrApiAccess::$user->rights->facture->creer) {
1085  throw new RestException(401);
1086  }
1087 
1088  $result = $this->invoice->fetch($id);
1089  if (!$result) {
1090  throw new RestException(404, 'Invoice not found');
1091  }
1092 
1093  if (!DolibarrApi::_checkAccessToResource('facture', $this->invoice->id)) {
1094  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1095  }
1096 
1097  if ($this->invoice->paye) {
1098  throw new RestException(500, 'Alreay paid');
1099  }
1100 
1101  $this->invoice->fetch($id);
1102  $this->invoice->fetch_thirdparty();
1103 
1104  // Check if there is already a discount (protection to avoid duplicate creation when resubmit post)
1105  $discountcheck = new DiscountAbsolute($this->db);
1106  $result = $discountcheck->fetch(0, $this->invoice->id);
1107 
1108  $canconvert = 0;
1109  if ($this->invoice->type == Facture::TYPE_DEPOSIT && empty($discountcheck->id)) {
1110  $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)
1111  }
1112  if (($this->invoice->type == Facture::TYPE_CREDIT_NOTE || $this->invoice->type == Facture::TYPE_STANDARD) && $this->invoice->paye == 0 && empty($discountcheck->id)) {
1113  $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)
1114  }
1115  if ($canconvert) {
1116  $this->db->begin();
1117 
1118  $amount_ht = $amount_tva = $amount_ttc = array();
1119  $multicurrency_amount_ht = $multicurrency_amount_tva = $multicurrency_amount_ttc = array();
1120 
1121  // Loop on each vat rate
1122  $i = 0;
1123  foreach ($this->invoice->lines as $line) {
1124  if ($line->product_type < 9 && $line->total_ht != 0) { // Remove lines with product_type greater than or equal to 9
1125  // no need to create discount if amount is null
1126  $amount_ht[$line->tva_tx] += $line->total_ht;
1127  $amount_tva[$line->tva_tx] += $line->total_tva;
1128  $amount_ttc[$line->tva_tx] += $line->total_ttc;
1129  $multicurrency_amount_ht[$line->tva_tx] += $line->multicurrency_total_ht;
1130  $multicurrency_amount_tva[$line->tva_tx] += $line->multicurrency_total_tva;
1131  $multicurrency_amount_ttc[$line->tva_tx] += $line->multicurrency_total_ttc;
1132  $i++;
1133  }
1134  }
1135 
1136  // Insert one discount by VAT rate category
1137  $discount = new DiscountAbsolute($this->db);
1138  if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) {
1139  $discount->description = '(CREDIT_NOTE)';
1140  } elseif ($this->invoice->type == Facture::TYPE_DEPOSIT) {
1141  $discount->description = '(DEPOSIT)';
1142  } elseif ($this->invoice->type == Facture::TYPE_STANDARD || $this->invoice->type == Facture::TYPE_REPLACEMENT || $this->invoice->type == Facture::TYPE_SITUATION) {
1143  $discount->description = '(EXCESS RECEIVED)';
1144  } else {
1145  throw new RestException(500, 'Cant convert to reduc an Invoice of this type');
1146  }
1147 
1148  $discount->fk_soc = $this->invoice->socid;
1149  $discount->fk_facture_source = $this->invoice->id;
1150 
1151  $error = 0;
1152 
1153  if ($this->invoice->type == Facture::TYPE_STANDARD || $this->invoice->type == Facture::TYPE_REPLACEMENT || $this->invoice->type == Facture::TYPE_SITUATION) {
1154  // If we're on a standard invoice, we have to get excess received to create a discount in TTC without VAT
1155 
1156  // Total payments
1157  $sql = 'SELECT SUM(pf.amount) as total_payments';
1158  $sql .= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf, '.MAIN_DB_PREFIX.'paiement as p';
1159  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as c ON p.fk_paiement = c.id';
1160  $sql .= ' WHERE pf.fk_facture = '.((int) $this->invoice->id);
1161  $sql .= ' AND pf.fk_paiement = p.rowid';
1162  $sql .= ' AND p.entity IN ('.getEntity('invoice').')';
1163  $resql = $this->db->query($sql);
1164  if (!$resql) {
1165  dol_print_error($this->db);
1166  }
1167 
1168  $res = $this->db->fetch_object($resql);
1169  $total_payments = $res->total_payments;
1170 
1171  // Total credit note and deposit
1172  $total_creditnote_and_deposit = 0;
1173  $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,";
1174  $sql .= " re.description, re.fk_facture_source";
1175  $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re";
1176  $sql .= " WHERE fk_facture = ".((int) $this->invoice->id);
1177  $resql = $this->db->query($sql);
1178  if (!empty($resql)) {
1179  while ($obj = $this->db->fetch_object($resql)) {
1180  $total_creditnote_and_deposit += $obj->amount_ttc;
1181  }
1182  } else {
1183  dol_print_error($this->db);
1184  }
1185 
1186  $discount->amount_ht = $discount->amount_ttc = $total_payments + $total_creditnote_and_deposit - $this->invoice->total_ttc;
1187  $discount->amount_tva = 0;
1188  $discount->tva_tx = 0;
1189 
1190  $result = $discount->create(DolibarrApiAccess::$user);
1191  if ($result < 0) {
1192  $error++;
1193  }
1194  }
1195  if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE || $this->invoice->type == Facture::TYPE_DEPOSIT) {
1196  foreach ($amount_ht as $tva_tx => $xxx) {
1197  $discount->amount_ht = abs($amount_ht[$tva_tx]);
1198  $discount->amount_tva = abs($amount_tva[$tva_tx]);
1199  $discount->amount_ttc = abs($amount_ttc[$tva_tx]);
1200  $discount->multicurrency_amount_ht = abs($multicurrency_amount_ht[$tva_tx]);
1201  $discount->multicurrency_amount_tva = abs($multicurrency_amount_tva[$tva_tx]);
1202  $discount->multicurrency_amount_ttc = abs($multicurrency_amount_ttc[$tva_tx]);
1203  $discount->tva_tx = abs($tva_tx);
1204 
1205  $result = $discount->create(DolibarrApiAccess::$user);
1206  if ($result < 0) {
1207  $error++;
1208  break;
1209  }
1210  }
1211  }
1212 
1213  if (empty($error)) {
1214  if ($this->invoice->type != Facture::TYPE_DEPOSIT) {
1215  // Classe facture
1216  $result = $this->invoice->setPaid(DolibarrApiAccess::$user);
1217  if ($result >= 0) {
1218  $this->db->commit();
1219  } else {
1220  $this->db->rollback();
1221  throw new RestException(500, 'Could not set paid');
1222  }
1223  } else {
1224  $this->db->commit();
1225  }
1226  } else {
1227  $this->db->rollback();
1228  throw new RestException(500, 'Discount creation error');
1229  }
1230  }
1231 
1232  return $this->_cleanObjectDatas($this->invoice);
1233  }
1234 
1252  public function useDiscount($id, $discountid)
1253  {
1254 
1255  if (!DolibarrApiAccess::$user->rights->facture->creer) {
1256  throw new RestException(401);
1257  }
1258  if (empty($id)) {
1259  throw new RestException(400, 'Invoice ID is mandatory');
1260  }
1261  if (empty($discountid)) {
1262  throw new RestException(400, 'Discount ID is mandatory');
1263  }
1264 
1265  if (!DolibarrApi::_checkAccessToResource('facture', $id)) {
1266  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1267  }
1268 
1269  $result = $this->invoice->fetch($id);
1270  if (!$result) {
1271  throw new RestException(404, 'Invoice not found');
1272  }
1273 
1274  $result = $this->invoice->insert_discount($discountid);
1275  if ($result < 0) {
1276  throw new RestException(405, $this->invoice->error);
1277  }
1278 
1279  return $result;
1280  }
1281 
1299  public function useCreditNote($id, $discountid)
1300  {
1301 
1302  require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
1303 
1304  if (!DolibarrApiAccess::$user->rights->facture->creer) {
1305  throw new RestException(401);
1306  }
1307  if (empty($id)) {
1308  throw new RestException(400, 'Invoice ID is mandatory');
1309  }
1310  if (empty($discountid)) {
1311  throw new RestException(400, 'Credit ID is mandatory');
1312  }
1313 
1314  if (!DolibarrApi::_checkAccessToResource('facture', $id)) {
1315  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1316  }
1317  $discount = new DiscountAbsolute($this->db);
1318  $result = $discount->fetch($discountid);
1319  if (!$result) {
1320  throw new RestException(404, 'Credit not found');
1321  }
1322 
1323  $result = $discount->link_to_invoice(0, $id);
1324  if ($result < 0) {
1325  throw new RestException(405, $discount->error);
1326  }
1327 
1328  return $result;
1329  }
1330 
1345  public function getPayments($id)
1346  {
1347 
1348  if (!DolibarrApiAccess::$user->rights->facture->lire) {
1349  throw new RestException(401);
1350  }
1351  if (empty($id)) {
1352  throw new RestException(400, 'Invoice ID is mandatory');
1353  }
1354 
1355  if (!DolibarrApi::_checkAccessToResource('facture', $id)) {
1356  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1357  }
1358 
1359  $result = $this->invoice->fetch($id);
1360  if (!$result) {
1361  throw new RestException(404, 'Invoice not found');
1362  }
1363 
1364  $result = $this->invoice->getListOfPayments();
1365  if ($result < 0) {
1366  throw new RestException(405, $this->invoice->error);
1367  }
1368 
1369  return $result;
1370  }
1371 
1372 
1394  public function addPayment($id, $datepaye, $paymentid, $closepaidinvoices, $accountid, $num_payment = '', $comment = '', $chqemetteur = '', $chqbank = '')
1395  {
1396  global $conf;
1397 
1398  require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
1399 
1400  if (!DolibarrApiAccess::$user->rights->facture->creer) {
1401  throw new RestException(403);
1402  }
1403  if (empty($id)) {
1404  throw new RestException(400, 'Invoice ID is mandatory');
1405  }
1406 
1407  if (!DolibarrApi::_checkAccessToResource('facture', $id)) {
1408  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1409  }
1410 
1411  if (isModEnabled('banque')) {
1412  if (empty($accountid)) {
1413  throw new RestException(400, 'Account ID is mandatory');
1414  }
1415  }
1416 
1417  if (empty($paymentid)) {
1418  throw new RestException(400, 'Payment ID or Payment Code is mandatory');
1419  }
1420 
1421 
1422  $result = $this->invoice->fetch($id);
1423  if (!$result) {
1424  throw new RestException(404, 'Invoice not found');
1425  }
1426 
1427  // Calculate amount to pay
1428  $totalpaid = $this->invoice->getSommePaiement();
1429  $totalcreditnotes = $this->invoice->getSumCreditNotesUsed();
1430  $totaldeposits = $this->invoice->getSumDepositsUsed();
1431  $resteapayer = price2num($this->invoice->total_ttc - $totalpaid - $totalcreditnotes - $totaldeposits, 'MT');
1432 
1433  $this->db->begin();
1434 
1435  $amounts = array();
1436  $multicurrency_amounts = array();
1437 
1438  // Clean parameters amount if payment is for a credit note
1439  if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) {
1440  $resteapayer = price2num($resteapayer, 'MT');
1441  $amounts[$id] = -$resteapayer;
1442  // Multicurrency
1443  $newvalue = price2num($this->invoice->multicurrency_total_ttc, 'MT');
1444  $multicurrency_amounts[$id] = -$newvalue;
1445  } else {
1446  $resteapayer = price2num($resteapayer, 'MT');
1447  $amounts[$id] = $resteapayer;
1448  // Multicurrency
1449  $newvalue = price2num($this->invoice->multicurrency_total_ttc, 'MT');
1450  $multicurrency_amounts[$id] = $newvalue;
1451  }
1452 
1453  // Creation of payment line
1454  $paymentobj = new Paiement($this->db);
1455  $paymentobj->datepaye = $datepaye;
1456  $paymentobj->amounts = $amounts; // Array with all payments dispatching with invoice id
1457  $paymentobj->multicurrency_amounts = $multicurrency_amounts; // Array with all payments dispatching
1458  $paymentobj->paiementid = $paymentid;
1459  $paymentobj->paiementcode = dol_getIdFromCode($this->db, $paymentid, 'c_paiement', 'id', 'code', 1);
1460  $paymentobj->num_payment = $num_payment;
1461  $paymentobj->note_private = $comment;
1462 
1463  $payment_id = $paymentobj->create(DolibarrApiAccess::$user, ($closepaidinvoices == 'yes' ? 1 : 0)); // This include closing invoices
1464  if ($payment_id < 0) {
1465  $this->db->rollback();
1466  throw new RestException(400, 'Payment error : '.$paymentobj->error);
1467  }
1468 
1469  if (isModEnabled('banque')) {
1470  $label = '(CustomerInvoicePayment)';
1471 
1472  if ($paymentobj->paiementcode == 'CHQ' && empty($chqemetteur)) {
1473  throw new RestException(400, 'Emetteur is mandatory when payment code is '.$paymentobj->paiementcode);
1474  }
1475  if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) {
1476  $label = '(CustomerInvoicePaymentBack)'; // Refund of a credit note
1477  }
1478  $result = $paymentobj->addPaymentToBank(DolibarrApiAccess::$user, 'payment', $label, $accountid, $chqemetteur, $chqbank);
1479  if ($result < 0) {
1480  $this->db->rollback();
1481  throw new RestException(400, 'Add payment to bank error : '.$paymentobj->error);
1482  }
1483  }
1484 
1485  $this->db->commit();
1486 
1487  return $payment_id;
1488  }
1489 
1515  public function addPaymentDistributed($arrayofamounts, $datepaye, $paymentid, $closepaidinvoices, $accountid, $num_payment = '', $comment = '', $chqemetteur = '', $chqbank = '', $ref_ext = '', $accepthigherpayment = false)
1516  {
1517  global $conf;
1518 
1519  require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
1520 
1521  if (!DolibarrApiAccess::$user->rights->facture->creer) {
1522  throw new RestException(403);
1523  }
1524  foreach ($arrayofamounts as $id => $amount) {
1525  if (empty($id)) {
1526  throw new RestException(400, 'Invoice ID is mandatory. Fill the invoice id and amount into arrayofamounts parameter. For example: {"1": "99.99", "2": "10"}');
1527  }
1528  if (!DolibarrApi::_checkAccessToResource('facture', $id)) {
1529  throw new RestException(403, 'Access not allowed on invoice ID '.$id.' for login '.DolibarrApiAccess::$user->login);
1530  }
1531  }
1532 
1533  if (isModEnabled('banque')) {
1534  if (empty($accountid)) {
1535  throw new RestException(400, 'Account ID is mandatory');
1536  }
1537  }
1538  if (empty($paymentid)) {
1539  throw new RestException(400, 'Payment ID or Payment Code is mandatory');
1540  }
1541 
1542  $this->db->begin();
1543 
1544  $amounts = array();
1545  $multicurrency_amounts = array();
1546 
1547  // Loop on each invoice to pay
1548  foreach ($arrayofamounts as $id => $amountarray) {
1549  $result = $this->invoice->fetch($id);
1550  if (!$result) {
1551  $this->db->rollback();
1552  throw new RestException(404, 'Invoice ID '.$id.' not found');
1553  }
1554 
1555  if (($amountarray["amount"] == "remain" || $amountarray["amount"] > 0) && ($amountarray["multicurrency_amount"] == "remain" || $amountarray["multicurrency_amount"] > 0)) {
1556  $this->db->rollback();
1557  throw new RestException(400, 'Payment in both currency '.$id.' ( amount: '.$amountarray["amount"].', multicurrency_amount: '.$amountarray["multicurrency_amount"].')');
1558  }
1559 
1560  $is_multicurrency = 0;
1561  $total_ttc = $this->invoice->total_ttc;
1562 
1563  if ($amountarray["multicurrency_amount"] > 0 || $amountarray["multicurrency_amount"] == "remain") {
1564  $is_multicurrency = 1;
1565  $total_ttc = $this->invoice->multicurrency_total_ttc;
1566  }
1567 
1568  // Calculate amount to pay
1569  $totalpaid = $this->invoice->getSommePaiement($is_multicurrency);
1570  $totalcreditnotes = $this->invoice->getSumCreditNotesUsed($is_multicurrency);
1571  $totaldeposits = $this->invoice->getSumDepositsUsed($is_multicurrency);
1572  $remainstopay = $amount = price2num($total_ttc - $totalpaid - $totalcreditnotes - $totaldeposits, 'MT');
1573 
1574  if (!$is_multicurrency && $amountarray["amount"] != 'remain') {
1575  $amount = price2num($amountarray["amount"], 'MT');
1576  }
1577 
1578  if ($is_multicurrency && $amountarray["multicurrency_amount"] != 'remain') {
1579  $amount = price2num($amountarray["multicurrency_amount"], 'MT');
1580  }
1581 
1582  if ($amount > $remainstopay && !$accepthigherpayment) {
1583  $this->db->rollback();
1584  throw new RestException(400, 'Payment amount on invoice ID '.$id.' ('.$amount.') is higher than remain to pay ('.$remainstopay.')');
1585  }
1586 
1587  if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) {
1588  $amount = -$amount;
1589  }
1590 
1591  if ($is_multicurrency) {
1592  $amounts[$id] = null;
1593  // Multicurrency
1594  $multicurrency_amounts[$id] = $amount;
1595  } else {
1596  $amounts[$id] = $amount;
1597  // Multicurrency
1598  $multicurrency_amounts[$id] = null;
1599  }
1600  }
1601 
1602  // Creation of payment line
1603  $paymentobj = new Paiement($this->db);
1604  $paymentobj->datepaye = $datepaye;
1605  $paymentobj->amounts = $amounts; // Array with all payments dispatching with invoice id
1606  $paymentobj->multicurrency_amounts = $multicurrency_amounts; // Array with all payments dispatching
1607  $paymentobj->paiementid = $paymentid;
1608  $paymentobj->paiementcode = dol_getIdFromCode($this->db, $paymentid, 'c_paiement', 'id', 'code', 1);
1609  $paymentobj->num_payment = $num_payment;
1610  $paymentobj->note_private = $comment;
1611  $paymentobj->ref_ext = $ref_ext;
1612  $payment_id = $paymentobj->create(DolibarrApiAccess::$user, ($closepaidinvoices == 'yes' ? 1 : 0)); // This include closing invoices
1613  if ($payment_id < 0) {
1614  $this->db->rollback();
1615  throw new RestException(400, 'Payment error : '.$paymentobj->error);
1616  }
1617  if (isModEnabled('banque')) {
1618  $label = '(CustomerInvoicePayment)';
1619  if ($paymentobj->paiementcode == 'CHQ' && empty($chqemetteur)) {
1620  throw new RestException(400, 'Emetteur is mandatory when payment code is '.$paymentobj->paiementcode);
1621  }
1622  if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) {
1623  $label = '(CustomerInvoicePaymentBack)'; // Refund of a credit note
1624  }
1625  $result = $paymentobj->addPaymentToBank(DolibarrApiAccess::$user, 'payment', $label, $accountid, $chqemetteur, $chqbank);
1626  if ($result < 0) {
1627  $this->db->rollback();
1628  throw new RestException(400, 'Add payment to bank error : '.$paymentobj->error);
1629  }
1630  }
1631 
1632  $this->db->commit();
1633 
1634  return $payment_id;
1635  }
1636 
1650  public function putPayment($id, $num_payment = '')
1651  {
1652  require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
1653 
1654  if (!DolibarrApiAccess::$user->rights->facture->creer) {
1655  throw new RestException(401);
1656  }
1657  if (empty($id)) {
1658  throw new RestException(400, 'Payment ID is mandatory');
1659  }
1660 
1661  $paymentobj = new Paiement($this->db);
1662  $result = $paymentobj->fetch($id);
1663 
1664  if (!$result) {
1665  throw new RestException(404, 'Payment not found');
1666  }
1667 
1668  if (!empty($num_payment)) {
1669  $result = $paymentobj->update_num($num_payment);
1670  if ($result < 0) {
1671  throw new RestException(500, 'Error when updating the payment num');
1672  }
1673  }
1674 
1675  return [
1676  'success' => [
1677  'code' => 200,
1678  'message' => 'Payment updated'
1679  ]
1680  ];
1681  }
1682 
1683  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1690  protected function _cleanObjectDatas($object)
1691  {
1692  // phpcs:enable
1693  $object = parent::_cleanObjectDatas($object);
1694 
1695  unset($object->note);
1696  unset($object->address);
1697  unset($object->barcode_type);
1698  unset($object->barcode_type_code);
1699  unset($object->barcode_type_label);
1700  unset($object->barcode_type_coder);
1701  unset($object->canvas);
1702 
1703  return $object;
1704  }
1705 
1714  private function _validate($data)
1715  {
1716  $invoice = array();
1717  foreach (Invoices::$FIELDS as $field) {
1718  if (!isset($data[$field])) {
1719  throw new RestException(400, "$field field missing");
1720  }
1721  $invoice[$field] = $data[$field];
1722  }
1723  return $invoice;
1724  }
1725 
1726 
1740  public function getTemplateInvoice($id, $contact_list = 1)
1741  {
1742  return $this->_fetchTemplateInvoice($id, '', '', $contact_list);
1743  }
1744 
1758  private function _fetchTemplateInvoice($id, $ref = '', $ref_ext = '', $contact_list = 1)
1759  {
1760  if (!DolibarrApiAccess::$user->rights->facture->lire) {
1761  throw new RestException(401);
1762  }
1763 
1764  $result = $this->template_invoice->fetch($id, $ref, $ref_ext);
1765  if (!$result) {
1766  throw new RestException(404, 'Template invoice not found');
1767  }
1768 
1769  if (!DolibarrApi::_checkAccessToResource('facturerec', $this->template_invoice->id)) {
1770  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1771  }
1772 
1773  // Add external contacts ids
1774  if ($contact_list > -1) {
1775  $tmparray = $this->template_invoice->liste_contact(-1, 'external', $contact_list);
1776  if (is_array($tmparray)) {
1777  $this->template_invoice->contacts_ids = $tmparray;
1778  }
1779  }
1780 
1781  $this->template_invoice->fetchObjectLinked();
1782  return $this->_cleanTemplateObjectDatas($this->template_invoice);
1783  }
1784 
1785 
1786  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1793  protected function _cleanTemplateObjectDatas($object)
1794  {
1795  // phpcs:enable
1796  $object = parent::_cleanObjectDatas($object);
1797 
1798  unset($object->note);
1799  unset($object->address);
1800  unset($object->barcode_type);
1801  unset($object->barcode_type_code);
1802  unset($object->barcode_type_label);
1803  unset($object->barcode_type_coder);
1804  unset($object->canvas);
1805 
1806  return $object;
1807  }
1808 }
Invoices\getTemplateInvoice
getTemplateInvoice($id, $contact_list=1)
Get properties of a template invoice object.
Definition: api_invoices.class.php:1740
Invoices\getDiscount
getDiscount($id)
Get discount from invoice.
Definition: api_invoices.class.php:1037
db
$conf db
API class for accounts.
Definition: inc.php:41
Invoices\settodraft
settodraft($id, $idwarehouse=-1)
Sets an invoice as draft.
Definition: api_invoices.class.php:841
Invoices\getLines
getLines($id)
Get lines of an invoice.
Definition: api_invoices.class.php:377
Invoices\_validate
_validate($data)
Validate fields before create or update object.
Definition: api_invoices.class.php:1714
Invoices\putLine
putLine($id, $lineid, $request_data=null)
Update a line to a given invoice.
Definition: api_invoices.class.php:414
Invoices\put
put($id, $request_data=null)
Update invoice.
Definition: api_invoices.class.php:612
Invoices\markAsCreditAvailable
markAsCreditAvailable($id)
Create a discount (credit available) for a credit note or a deposit.
Definition: api_invoices.class.php:1080
dol_print_error
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
Definition: functions.lib.php:4844
Invoices\useDiscount
useDiscount($id, $discountid)
Add a discount line into an invoice (as an invoice line) using an existing absolute discount.
Definition: api_invoices.class.php:1252
Invoices\_fetchTemplateInvoice
_fetchTemplateInvoice($id, $ref='', $ref_ext='', $contact_list=1)
Get properties of an invoice object.
Definition: api_invoices.class.php:1758
FactureRec
Class to manage invoice templates.
Definition: facture-rec.class.php:40
Invoices\addPayment
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.
Definition: api_invoices.class.php:1394
Invoices\addPaymentDistributed
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.
Definition: api_invoices.class.php:1515
sanitizeVal
sanitizeVal($out='', $check='alphanohtml', $filter=null, $options=null)
Return a sanitized or empty value after checking value against a rule.
Definition: functions.lib.php:825
DolibarrApi\_checkAccessToResource
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
Facture
Class to manage invoices.
Definition: facture.class.php:60
Invoices
Definition: api_invoices.class.php:31
Invoices\createInvoiceFromOrder
createInvoiceFromOrder($orderid)
Create an invoice using an existing order.
Definition: api_invoices.class.php:339
Invoices\_cleanObjectDatas
_cleanObjectDatas($object)
Clean sensible object datas.
Definition: api_invoices.class.php:1690
price2num
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
Definition: functions.lib.php:5661
Invoices\putPayment
putPayment($id, $num_payment='')
Update a payment.
Definition: api_invoices.class.php:1650
Facture\TYPE_DEPOSIT
const TYPE_DEPOSIT
Deposit invoice.
Definition: facture.class.php:397
DolibarrApi
Class for API REST v1.
Definition: api.class.php:30
Invoices\settounpaid
settounpaid($id)
Sets an invoice as unpaid.
Definition: api_invoices.class.php:993
Facture\TYPE_REPLACEMENT
const TYPE_REPLACEMENT
Replacement invoice.
Definition: facture.class.php:387
dol_getIdFromCode
dol_getIdFromCode($db, $key, $tablename, $fieldkey='code', $fieldid='id', $entityfilter=0, $filters='')
Return an id or code from a code or id.
Definition: functions.lib.php:8535
Invoices\postLine
postLine($id, $request_data=null)
Add a line to a given invoice.
Definition: api_invoices.class.php:704
Invoices\deleteLine
deleteLine($id, $lineid)
Deletes a line of a given invoice.
Definition: api_invoices.class.php:576
Invoices\useCreditNote
useCreditNote($id, $discountid)
Add an available credit note discount to payments of an existing invoice.
Definition: api_invoices.class.php:1299
Commande
Class to manage customers orders.
Definition: commande.class.php:46
DolibarrApi\_checkFilters
_checkFilters($sqlfilters, &$error='')
Return if a $sqlfilters parameter is valid.
Definition: api.class.php:310
Invoices\postContact
postContact($id, $contactid, $type)
Add a contact type of given invoice.
Definition: api_invoices.class.php:486
Invoices\getByRef
getByRef($ref, $contact_list=1)
Get properties of an invoice object by ref.
Definition: api_invoices.class.php:92
DiscountAbsolute
Class to manage absolute discounts.
Definition: discount.class.php:29
Invoices\getByRefExt
getByRefExt($ref_ext, $contact_list=1)
Get properties of an invoice object by ref_ext.
Definition: api_invoices.class.php:110
Invoices\_fetch
_fetch($id, $ref='', $ref_ext='', $contact_list=1)
Get properties of an invoice object.
Definition: api_invoices.class.php:128
Invoices\_cleanTemplateObjectDatas
_cleanTemplateObjectDatas($object)
Clean sensible object datas.
Definition: api_invoices.class.php:1793
Invoices\addContact
addContact($id, $fk_socpeople, $type_contact, $source, $notrigger=0)
Adds a contact to an invoice.
Definition: api_invoices.class.php:792
isModEnabled
isModEnabled($module)
Is Dolibarr module enabled.
Definition: functions.lib.php:105
Facture\TYPE_CREDIT_NOTE
const TYPE_CREDIT_NOTE
Credit note invoice.
Definition: facture.class.php:392
Paiement
Class to manage payments of customer invoices.
Definition: paiement.class.php:41
Facture\TYPE_STANDARD
const TYPE_STANDARD
Standard invoice.
Definition: facture.class.php:382
getMarginInfos
getMarginInfos($pvht, $remise_percent, $tva_tx, $localtax1_tx, $localtax2_tx, $fk_pa, $paht)
Return an array with margins information of a line.
Definition: margins.lib.php:117
dol_now
dol_now($mode='auto')
Return date for now.
Definition: functions.lib.php:2845
$resql
if(isModEnabled('facture') &&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->facture->lire)||(isModEnabled('supplier_invoice') && $user->rights->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->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:742
Invoices\__construct
__construct()
Constructor.
Definition: api_invoices.class.php:55
Invoices\deleteContact
deleteContact($id, $contactid, $type)
Delete a contact type of given invoice.
Definition: api_invoices.class.php:530
Invoices\validate
validate($id, $idwarehouse=0, $notrigger=0)
Validate an invoice.
Definition: api_invoices.class.php:893
Facture\TYPE_SITUATION
const TYPE_SITUATION
Situation invoice.
Definition: facture.class.php:407
Invoices\post
post($request_data=null)
Create invoice object.
Definition: api_invoices.class.php:296
Invoices\getPayments
getPayments($id)
Get list of payments of a given invoice.
Definition: api_invoices.class.php:1345
Invoices\settopaid
settopaid($id, $close_code='', $close_note='')
Sets an invoice as paid.
Definition: api_invoices.class.php:943
Invoices\index
index($sortfield="t.rowid", $sortorder='ASC', $limit=100, $page=0, $thirdparty_ids='', $status='', $sqlfilters='')
List invoices.
Definition: api_invoices.class.php:179