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