dolibarr 18.0.6
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
19use Luracast\Restler\RestException;
20
21require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
22require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php';
23
24
31class 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 ((int) $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.
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.
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.
getMarginInfos($pvht, $remise_percent, $tva_tx, $localtax1_tx, $localtax2_tx, $fk_pa, $paht)
Return an array with margins information of a line.