dolibarr 25.0.0-alpha
api_thirdparties.class.php
1<?php
2/* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
3 * Copyright (C) 2018 Pierre Chéné <pierre.chene44@gmail.com>
4 * Copyright (C) 2019 Cedric Ancelin <icedo.anc@gmail.com>
5 * Copyright (C) 2020-2025 Frédéric France <frederic.france@free.fr>
6 * Copyright (C) 2023 Alexandre Janniaux <alexandre.janniaux@gmail.com>
7 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
8 * Copyright (C) 2024 Jon Bendtsen <jon.bendtsen.github@jonb.dk>
9 * Copyright (C) 2025 William Mead <william@m34d.com>
10 * Copyright (C) 2025 Charlene Benke <charlene@patas-monkey.com>
11 * Copyright (C) 2026 Benjamin Falière <benjamin@faliere.com>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <https://www.gnu.org/licenses/>.
25 */
26
27use Luracast\Restler\RestException;
28
38{
42 public static $FIELDS = array(
43 'name'
44 );
45
49 public $company;
50
54 public function __construct()
55 {
56 global $db;
57 $this->db = $db;
58
59 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
60 require_once DOL_DOCUMENT_ROOT.'/societe/class/societeaccount.class.php';
61 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
62 require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php';
63 require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
64
65 $this->company = new Societe($this->db);
66
67 if (getDolGlobalString('SOCIETE_EMAIL_MANDATORY')) {
68 static::$FIELDS[] = 'email';
69 }
70 }
71
84 public function get($id)
85 {
86 return $this->_fetch($id);
87 }
88
105 public function getByEmail($email)
106 {
107 return $this->_fetch(null, '', '', '', '', '', '', '', '', '', $email);
108 }
109
124 public function getByBarcode($barcode)
125 {
126 return $this->_fetch(null, '', '', $barcode);
127 }
128
155 public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $mode = 0, $category = 0, $sqlfilters = '', $properties = '', $pagination_data = false)
156 {
157 $obj_ret = array();
158
159 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
160 throw new RestException(403);
161 }
162
163 // case of external user, we force socids
164 $socids = DolibarrApiAccess::$user->socid ? (string) DolibarrApiAccess::$user->socid : '';
165
166 // If the internal user must only see his customers, force searching by him
167 $search_sale = 0;
168 if (!DolibarrApiAccess::$user->hasRight('societe', 'client', 'voir') && !$socids) {
169 $search_sale = DolibarrApiAccess::$user->id;
170 }
171
172 $sql = "SELECT t.rowid";
173 $sql .= " FROM ".MAIN_DB_PREFIX."societe as t";
174 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_extrafields AS ef ON ef.fk_object = t.rowid"; // So we will be able to filter on extrafields
175 if ($category > 0) {
176 if ($mode != 4) {
177 $sql .= ", ".MAIN_DB_PREFIX."categorie_societe as c";
178 }
179 if (!in_array($mode, array(1, 2, 3))) {
180 $sql .= ", ".MAIN_DB_PREFIX."categorie_fournisseur as cc";
181 }
182 }
183 $sql .= " WHERE t.entity IN (".getEntity('societe').")";
184 if ($mode == 1) {
185 $sql .= " AND t.client IN (1, 3)";
186 } elseif ($mode == 2) {
187 $sql .= " AND t.client IN (2, 3)";
188 } elseif ($mode == 3) {
189 $sql .= " AND t.client IN (0)";
190 } elseif ($mode == 4) {
191 $sql .= " AND t.fournisseur IN (1)";
192 }
193 // Select third parties of a given category
194 if ($category > 0) {
195 if (!empty($mode) && $mode != 4) {
196 $sql .= " AND c.fk_categorie = ".((int) $category)." AND c.fk_soc = t.rowid";
197 } elseif (!empty($mode) && $mode == 4) {
198 $sql .= " AND cc.fk_categorie = ".((int) $category)." AND cc.fk_soc = t.rowid";
199 } else {
200 $sql .= " AND ((c.fk_categorie = ".((int) $category)." AND c.fk_soc = t.rowid) OR (cc.fk_categorie = ".((int) $category)." AND cc.fk_soc = t.rowid))";
201 }
202 }
203 if ($socids) {
204 $sql .= " AND t.rowid IN (".$this->db->sanitize($socids).")";
205 }
206 // Search on sale representative
207 if ($search_sale && $search_sale != '-1') {
208 if ($search_sale == -2) {
209 $sql .= " AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = t.rowid)";
210 } elseif ($search_sale > 0) {
211 $sql .= " AND EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = t.rowid AND sc.fk_user = ".((int) $search_sale).")";
212 }
213 }
214 // Add sql filters
215 if ($sqlfilters) {
216 $errormessage = '';
217 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
218 if ($errormessage) {
219 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
220 }
221 }
222
223 //this query will return total thirdparties with the filters given
224 $sqlTotals = str_replace('SELECT t.rowid', 'SELECT count(t.rowid) as total', $sql);
225
226 $sql .= $this->db->order($sortfield, $sortorder);
227 if ($limit) {
228 if ($page < 0) {
229 $page = 0;
230 }
231 $offset = $limit * $page;
232
233 $sql .= $this->db->plimit($limit + 1, $offset);
234 }
235
236 $result = $this->db->query($sql);
237 if ($result) {
238 $num = $this->db->num_rows($result);
239 $min = min($num, ($limit <= 0 ? $num : $limit));
240 $i = 0;
241 while ($i < $min) {
242 $obj = $this->db->fetch_object($result);
243 $soc_static = new Societe($this->db);
244 if ($soc_static->fetch($obj->rowid)) {
245 if (isModEnabled('mailing')) {
246 $soc_static->getNoEmail();
247 }
248 $obj_ret[] = $this->_filterObjectProperties($this->_cleanObjectDatas($soc_static), $properties);
249 }
250 $i++;
251 }
252 } else {
253 throw new RestException(503, 'Error when retrieve third parties : '.$this->db->lasterror());
254 }
255 if (!count($obj_ret)) {
256 $message = '';
257 switch ($mode) {
258 case 0:
259 $message = 'No third parties found';
260 break;
261 case 1:
262 $message = 'No customers found';
263 break;
264 case 2:
265 $message = 'No prospects found';
266 break;
267 case 3:
268 $message = 'No other third parties found';
269 break;
270 case 4:
271 $message = 'No suppliers found';
272 }
273 throw new RestException(404, $message);
274 }
275
276 //if $pagination_data is true, the response will contain element data with all values and element pagination with pagination data(total,page,limit)
277 if ($pagination_data) {
278 $totalsResult = $this->db->query($sqlTotals);
279 $total = $this->db->fetch_object($totalsResult)->total;
280
281 $tmp = $obj_ret;
282 $obj_ret = [];
283
284 $obj_ret['data'] = $tmp;
285 $obj_ret['pagination'] = [
286 'total' => (int) $total,
287 'page' => $page, //count starts from 0
288 'page_count' => ceil((int) $total / $limit),
289 'limit' => $limit
290 ];
291 }
292
293 return $obj_ret;
294 }
295
308 public function post($request_data = null)
309 {
310 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
311 throw new RestException(403);
312 }
313
314 // External api user does not know internal country ID
315 if (!isset($request_data['country_id']) && isset($request_data['country_code'])) {
316 $field = strlen($request_data['country_code']) > 2 ? 'code_iso' : 'code';
317 $id = dol_getIdFromCode($this->db, $request_data['country_code'], "c_country", $field, "rowid");
318 if ($id < 0) {
319 throw new RestException(404, 'Country code not found in database: ' . $this->db->error);
320 }
321 $request_data['country_id'] = $id;
322 }
323
324 // Check mandatory fields
325 $result = $this->_validate($request_data);
326
327 foreach ($request_data as $field => $value) {
328 if ($field === 'caller') {
329 // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
330 $this->company->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
331 continue;
332 }
333 if ($field == 'array_options' && is_array($value)) {
334 $this->company->fetch_optionals(); // To force the load of the extrafields definition by fetch_name_optionals_label()
335
336 foreach ($value as $index => $val) {
337 $this->company->array_options[$index] = $this->_checkValExtrafieldsForAPI($index, $val, $this->company);
338 }
339 continue;
340 }
341
342 $this->company->$field = $this->_checkValForAPI($field, $value, $this->company);
343 }
344
345 if ($this->company->create(DolibarrApiAccess::$user) < 0) {
346 throw new RestException(500, 'Error creating thirdparty', array_merge(array($this->company->error), $this->company->errors));
347 }
348 if (isModEnabled('mailing') && !empty($this->company->email) && isset($this->company->no_email)) {
349 $this->company->setNoEmail($this->company->no_email);
350 }
351
352 return $this->company->id;
353 }
354
372 public function put($id, $request_data = null)
373 {
374 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
375 throw new RestException(403);
376 }
377
378 $result = $this->company->fetch($id);
379 if (!$result) {
380 throw new RestException(404, 'Thirdparty not found');
381 }
382
383 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
384 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
385 }
386
387 foreach ($request_data as $field => $value) {
388 if ($field == 'id') {
389 continue;
390 }
391 if ($field === 'caller') {
392 // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
393 $this->company->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
394 continue;
395 }
396 if ($field == 'array_options' && is_array($value)) {
397 foreach ($value as $index => $val) {
398 $this->company->array_options[$index] = $this->_checkValExtrafieldsForAPI($index, $val, $this->company);
399 }
400 continue;
401 }
402 $this->company->$field = $this->_checkValForAPI($field, $value, $this->company);
403 }
404
405 if (isModEnabled('mailing') && !empty($this->company->email) && isset($this->company->no_email)) {
406 $this->company->setNoEmail($this->company->no_email);
407 }
408
409 if ($this->company->update($id, DolibarrApiAccess::$user, 1, 1, 1, 'update', 1) > 0) {
410 return $this->get($id);
411 } else {
412 throw new RestException(500, $this->company->error);
413 }
414 }
415
437 public function merge($id, $idtodelete)
438 {
439 if ($id == $idtodelete) {
440 throw new RestException(400, 'Try to merge a thirdparty into itself');
441 }
442
443 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
444 throw new RestException(403);
445 }
446
447 $result = $this->company->fetch($id); // include the fetch of extra fields
448 if (!$result) {
449 throw new RestException(404, 'Thirdparty not found');
450 }
451
452 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
453 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
454 }
455
456 $companytoremove = new Societe($this->db);
457 $result = $companytoremove->fetch($idtodelete); // include the fetch of extra fields
458 if (!$result) {
459 throw new RestException(404, 'Thirdparty not found');
460 }
461
462 if (!DolibarrApi::_checkAccessToResource('societe', $companytoremove->id)) {
463 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
464 }
465
466 $user = DolibarrApiAccess::$user;
467 $result = $this->company->mergeCompany($companytoremove->id);
468 if ($result < 0) {
469 throw new RestException(500, 'Error failed to merged thirdparty '.$companytoremove->id.' into '.$id.'. Enable and read log file for more information.');
470 }
471
472 return $this->get($id);
473 }
474
487 public function delete($id)
488 {
489 if (!DolibarrApiAccess::$user->hasRight('societe', 'supprimer')) {
490 throw new RestException(403);
491 }
492 $result = $this->company->fetch($id);
493 if (!$result) {
494 throw new RestException(404, 'Thirdparty not found');
495 }
496 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
497 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
498 }
499 $this->company->oldcopy = clone $this->company; // @phan-suppress-current-line PhanTypeMismatchProperty
500
501 $res = $this->company->delete($id);
502 if ($res < 0) {
503 throw new RestException(500, "Can't delete, error occurs");
504 } elseif ($res == 0) {
505 throw new RestException(409, "Can't delete, that product is probably used");
506 }
507
508 return array(
509 'success' => array(
510 'code' => 200,
511 'message' => 'Object deleted'
512 )
513 );
514 }
515
533 public function setThirdpartyPriceLevel($id, $priceLevel)
534 {
535 global $conf;
536
537 if (!isModEnabled('societe')) {
538 throw new RestException(501, 'Module "Thirdparties" needed for this request');
539 }
540
541 if (!isModEnabled("product")) {
542 throw new RestException(501, 'Module "Products" needed for this request');
543 }
544
545 if (!getDolGlobalString('PRODUIT_MULTIPRICES') && !getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) {
546 throw new RestException(501, 'Multiprices features activation needed for this request');
547 }
548
549 if ($priceLevel < 1 || $priceLevel > getDolGlobalString('PRODUIT_MULTIPRICES_LIMIT')) {
550 throw new RestException(400, 'Price level must be between 1 and ' . getDolGlobalString('PRODUIT_MULTIPRICES_LIMIT'));
551 }
552
553 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
554 throw new RestException(403, 'Access to thirdparty '.$id.' not allowed for login '.DolibarrApiAccess::$user->login);
555 }
556
557 $result = $this->company->fetch($id);
558 if ($result < 0) {
559 throw new RestException(404, 'Thirdparty '.$id.' not found');
560 }
561
562 if (empty($result)) {
563 throw new RestException(500, 'Error fetching thirdparty '.$id, array_merge(array($this->company->error), $this->company->errors));
564 }
565
566 if (empty(DolibarrApi::_checkAccessToResource('societe', $this->company->id))) {
567 throw new RestException(403, 'Access to thirdparty '.$id.' not allowed for login '.DolibarrApiAccess::$user->login);
568 }
569
570 $result = $this->company->setPriceLevel($priceLevel, DolibarrApiAccess::$user);
571 if ($result <= 0) {
572 throw new RestException(500, 'Error setting new price level for thirdparty '.$id, array($this->company->db->lasterror()));
573 }
574
575 return $this->_cleanObjectDatas($this->company);
576 }
577
591 public function getRepresentative($id)
592 {
593 if (!DolibarrApiAccess::$user->hasRight('societe', 'reader')) {
594 throw new RestException(403);
595 }
596 $result = $this->company->fetch($id);
597 if (!$result) {
598 throw new RestException(404, 'Thirdparty not found');
599 }
600 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
601 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
602 }
603 $result = $this->company->getSalesRepresentatives(DolibarrApiAccess::$user);
606 return $result;
607 }
608
623 public function addRepresentative($id, $representative_id)
624 {
625 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
626 throw new RestException(403);
627 }
628 $result = $this->company->fetch($id);
629 if (!$result) {
630 throw new RestException(404, 'Thirdparty not found');
631 }
632 $usertmp = new User($this->db);
633 $result = $usertmp->fetch($representative_id);
634 if (!$result) {
635 throw new RestException(404, 'User not found');
636 }
637 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
638 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
639 }
640 $result = $this->company->add_commercial(DolibarrApiAccess::$user, $representative_id);
641
642 return $result;
643 }
644
659 public function deleteRepresentative($id, $representative_id)
660 {
661 if (!DolibarrApiAccess::$user->hasRight('societe', 'supprimer')) {
662 throw new RestException(403);
663 }
664 $result = $this->company->fetch($id);
665 if (!$result) {
666 throw new RestException(404, 'Thirdparty not found');
667 }
668 $usertmp = new User($this->db);
669 $result = $usertmp->fetch($representative_id);
670 if (!$result) {
671 throw new RestException(404, 'User not found');
672 }
673 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
674 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
675 }
676 $result = $this->company->del_commercial(DolibarrApiAccess::$user, $representative_id);
677
678 return $result;
679 }
680
699 public function getCategories($id, $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0)
700 {
701 if (!DolibarrApiAccess::$user->hasRight('categorie', 'lire')) {
702 throw new RestException(403);
703 }
704
705 $result = $this->company->fetch($id);
706 if (!$result) {
707 throw new RestException(404, 'Thirdparty not found');
708 }
709
710 // Check that user has permission on thirdparty ID
711 if (!DolibarrApi::_checkAccessToResource('societe', $this->company)) {
712 throw new RestException(404, 'Third party not allowed for login '.DolibarrApiAccess::$user->login);
713 }
714
715 $categories = new Categorie($this->db);
716
717 $arrayofcateg = $categories->getListForItem($id, 'customer', $sortfield, $sortorder, $limit, $page);
718
719 if (is_numeric($arrayofcateg) && $arrayofcateg < 0) {
720 throw new RestException(503, 'Error when retrieve category list : '.$categories->error);
721 }
722
723 if (is_numeric($arrayofcateg) && $arrayofcateg >= 0) { // To fix a return of 0 instead of empty array of method getListForItem
724 return array();
725 }
726
727 return $arrayofcateg;
728 }
729
746 public function addCategory($id, $category_id)
747 {
748 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
749 throw new RestException(403);
750 }
751
752 $result = $this->company->fetch($id);
753 if (!$result) {
754 throw new RestException(404, 'Third party not found');
755 }
756 $category = new Categorie($this->db);
757 $result = $category->fetch($category_id);
758 if (!$result) {
759 throw new RestException(404, 'category not found');
760 }
761
762 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
763 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
764 }
765 if (!DolibarrApi::_checkAccessToResource('category', $category->id)) {
766 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
767 }
768
769 $category->add_type($this->company, 'customer');
770
771 return $this->_cleanObjectDatas($this->company);
772 }
773
790 public function deleteCategory($id, $category_id)
791 {
792 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
793 throw new RestException(403);
794 }
795
796 $result = $this->company->fetch($id);
797 if (!$result) {
798 throw new RestException(404, 'Thirdparty not found');
799 }
800 $category = new Categorie($this->db);
801 $result = $category->fetch($category_id);
802 if (!$result) {
803 throw new RestException(404, 'category not found');
804 }
805
806 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
807 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
808 }
809 if (!DolibarrApi::_checkAccessToResource('category', $category->id)) {
810 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
811 }
812
813 $category->del_type($this->company, 'customer');
814
815 return $this->_cleanObjectDatas($this->company);
816 }
817
837 public function getSupplierCategories($id, $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0)
838 {
839 if (!DolibarrApiAccess::$user->hasRight('categorie', 'lire')) {
840 throw new RestException(403);
841 }
842
843 $result = $this->company->fetch($id);
844 if (!$result) {
845 throw new RestException(404, 'Thirdparty not found');
846 }
847
848 // Check that user has permission on thirdparty ID
849 if (!DolibarrApi::_checkAccessToResource('societe', $this->company)) {
850 throw new RestException(404, 'Third party not allowed for login '.DolibarrApiAccess::$user->login);
851 }
852
853 $categories = new Categorie($this->db);
854
855 $result = $categories->getListForItem($id, 'supplier', $sortfield, $sortorder, $limit, $page);
856
857 if (is_numeric($result) && $result < 0) {
858 throw new RestException(503, 'Error when retrieve category list : '.$categories->error);
859 }
860
861 if (is_numeric($result) && $result == 0) { // To fix a return of 0 instead of empty array of method getListForItem
862 return array();
863 }
864
865 return $result;
866 }
867
884 public function addSupplierCategory($id, $category_id)
885 {
886 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
887 throw new RestException(403);
888 }
889
890 $result = $this->company->fetch($id);
891 if (!$result) {
892 throw new RestException(404, 'Thirdparty not found');
893 }
894 $category = new Categorie($this->db);
895 $result = $category->fetch($category_id);
896 if (!$result) {
897 throw new RestException(404, 'category not found');
898 }
899
900 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
901 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
902 }
903 if (!DolibarrApi::_checkAccessToResource('category', $category->id)) {
904 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
905 }
906
907 $category->add_type($this->company, 'supplier');
908
909 return $this->_cleanObjectDatas($this->company);
910 }
911
928 public function deleteSupplierCategory($id, $category_id)
929 {
930 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
931 throw new RestException(403);
932 }
933
934 $result = $this->company->fetch($id);
935 if (!$result) {
936 throw new RestException(404, 'Thirdparty not found');
937 }
938 $category = new Categorie($this->db);
939 $result = $category->fetch($category_id);
940 if (!$result) {
941 throw new RestException(404, 'category not found');
942 }
943
944 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
945 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
946 }
947 if (!DolibarrApi::_checkAccessToResource('category', $category->id)) {
948 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
949 }
950
951 $category->del_type($this->company, 'supplier');
952
953 return $this->_cleanObjectDatas($this->company);
954 }
955
956
975 public function getOutStandingProposals($id, $mode = 'customer')
976 {
977 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
978 throw new RestException(403);
979 }
980
981 if (empty($id)) {
982 throw new RestException(400, 'Thirdparty ID is mandatory');
983 }
984
985 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
986 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
987 }
988
989 $result = $this->company->fetch($id);
990 if (!$result) {
991 throw new RestException(404, 'Thirdparty not found');
992 }
993
994 $result = $this->company->getOutstandingProposals($mode);
995
996 unset($result['total_ht']);
997 unset($result['total_ttc']);
998
999 return $result;
1000 }
1001
1002
1021 public function getOutStandingOrder($id, $mode = 'customer')
1022 {
1023 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
1024 throw new RestException(403);
1025 }
1026
1027 if (empty($id)) {
1028 throw new RestException(400, 'Thirdparty ID is mandatory');
1029 }
1030
1031 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1032 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1033 }
1034
1035 $result = $this->company->fetch($id);
1036 if (!$result) {
1037 throw new RestException(404, 'Thirdparty not found');
1038 }
1039
1040 $result = $this->company->getOutstandingOrders($mode);
1041
1042 unset($result['total_ht']);
1043 unset($result['total_ttc']);
1044
1045 return $result;
1046 }
1047
1066 public function getOutStandingInvoices($id, $mode = 'customer')
1067 {
1068 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
1069 throw new RestException(403);
1070 }
1071
1072 if (empty($id)) {
1073 throw new RestException(400, 'Thirdparty ID is mandatory');
1074 }
1075
1076 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1077 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1078 }
1079
1080 $result = $this->company->fetch($id);
1081 if (!$result) {
1082 throw new RestException(404, 'Thirdparty not found');
1083 }
1084
1085 $result = $this->company->getOutstandingBills($mode);
1086
1087 unset($result['total_ht']);
1088 unset($result['total_ttc']);
1089
1090 return $result;
1091 }
1092
1111 public function getSalesRepresentatives($id, $mode = 0)
1112 {
1113 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
1114 throw new RestException(403);
1115 }
1116
1117 if (empty($id)) {
1118 throw new RestException(400, 'Thirdparty ID is mandatory');
1119 }
1120
1121 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1122 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1123 }
1124
1125 $result = $this->company->fetch($id);
1126 if ($result <= 0) {
1127 throw new RestException(404, 'Thirdparty not found');
1128 }
1129
1130 $result = $this->company->getSalesRepresentatives(DolibarrApiAccess::$user, $mode);
1131
1132 return $result;
1133 }
1134
1159 public function getFixedAmountDiscounts($id, $mode = 'customer', $filter = "none", $sortfield = "f.type", $sortorder = 'ASC')
1160 {
1161 $obj_ret = array();
1162
1163 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
1164 throw new RestException(403);
1165 }
1166
1167 if (empty($id)) {
1168 throw new RestException(400, 'Thirdparty ID is mandatory');
1169 }
1170
1171 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1172 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1173 }
1174
1175 $result = $this->company->fetch($id);
1176 if (!$result) {
1177 throw new RestException(404, 'Thirdparty not found');
1178 }
1179
1180 $sql = '';
1181 if ($mode === 'customer') {
1182 $sql = "SELECT f.ref, f.type as factype, re.fk_facture_source, re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc, re.description, re.fk_facture, re.fk_facture_line";
1183 $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re";
1184 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON f.rowid = re.fk_facture_source";
1185 $sql .= " WHERE re.fk_soc = ".((int) $id);
1186 if ($filter == "available") {
1187 $sql .= " AND re.fk_facture IS NULL AND re.fk_facture_line IS NULL";
1188 }
1189 if ($filter == "used") {
1190 $sql .= " AND (re.fk_facture IS NOT NULL OR re.fk_facture_line IS NOT NULL)";
1191 }
1192 } elseif ($mode === 'supplier') {
1193 $sql = "SELECT f.ref, f.type as factype, re.fk_invoice_supplier_source, re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc, re.description, re.fk_invoice_supplier, re.fk_invoice_supplier_line";
1194 $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re";
1195 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facture_fourn as f ON f.rowid = re.fk_invoice_supplier_source";
1196 $sql .= " WHERE f.rowid = re.fk_invoice_supplier_source AND re.fk_soc = ".((int) $id);
1197 if ($filter == "available") {
1198 $sql .= " AND re.fk_invoice_supplier IS NULL AND re.fk_invoice_supplier_line IS NULL";
1199 }
1200 if ($filter == "used") {
1201 $sql .= " AND (re.fk_invoice_supplier IS NOT NULL OR re.fk_invoice_supplier_line IS NOT NULL)";
1202 }
1203 }
1204
1205 $sql .= $this->db->order($sortfield, $sortorder);
1206
1207 $result = $this->db->query($sql);
1208 if (!$result) {
1209 throw new RestException(503, $this->db->lasterror());
1210 } else {
1211 //$num = $this->db->num_rows($result);
1212 while ($obj = $this->db->fetch_object($result)) {
1213 $obj_ret[] = $obj;
1214 }
1215 }
1216
1217 return $obj_ret;
1218 }
1219
1244 public function createFixedAmountDiscount($id, $request_data = null)
1245 {
1246 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
1247 throw new RestException(403);
1248 }
1249
1250 // Check mandatory fields
1251 if (empty($id)) {
1252 throw new RestException(400, 'Thirdparty ID is mandatory');
1253 }
1254 if (!isset($request_data['amount'])) {
1255 throw new RestException(400, 'Missing required field: amount');
1256 }
1257 if (!isset($request_data['description'])) {
1258 throw new RestException(400, 'Missing required field: description');
1259 }
1260
1261 // Check access to resource
1262 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1263 throw new RestException(401, 'Access not allowed for login'.DolibarrApiAccess::$user->login);
1264 }
1265
1266 // Fetch thirdparty to verify it exists
1267 if ($this->company->fetch($id) <= 0) {
1268 throw new RestException(404, 'Error creating discount, thirdparty not found');
1269 }
1270
1271
1272 // Validate amount
1273 if (!is_numeric($request_data['amount']) || $request_data['amount'] <= 0) {
1274 throw new RestException(400, 'Invalid amount_ht: must be a positive number');
1275 }
1276 $amount = (float) $request_data['amount'];
1277
1278 // Validate VAT rate
1279 if (isset($request_data['tva_tx']) && (!is_numeric($request_data['tva_tx']) || $request_data['tva_tx'] < 0)) {
1280 throw new RestException(400, 'Invalid tva_tx: must be a positive number or zero');
1281 }
1282 $tva_tx = isset($request_data['tva_tx']) ? (float) $request_data['tva_tx'] : 0;
1283
1284 // Get price base type (HT or TTC) : HT as default
1285 $price_base_type = 'HT';
1286 if (isset($request_data['price_base_type'])) {
1287 $price_base_type = strtoupper($request_data['price_base_type']);
1288 if ($price_base_type !== 'HT' && $price_base_type !== 'TTC') {
1289 throw new RestException(400, 'Invalid price_base_type: must be "HT" or "TTC"');
1290 }
1291 }
1292
1293 // Get discount type (0 = customer, 1 = supplier): 0 as default
1294 $discount_type = 0;
1295 if (isset($request_data['discount_type'])) {
1296 $discount_type = (int) $request_data['discount_type'];
1297 if ($discount_type !== 0 && $discount_type !== 1) {
1298 throw new RestException(400, 'Invalid discount_type: must be 0 (customer) or 1 (supplier)');
1299 }
1300 }
1301
1302 // Get description
1303 $description = $request_data['description'];
1304 if (empty(trim($description))) {
1305 throw new RestException(400, 'Description cannot be empty');
1306 }
1307
1308 // Prepare VAT rate with code if provided
1309 $vatrate = "";
1310 if (isset($request_data['vat_src_code']) && !empty($request_data['vat_src_code'])) {
1311 $vatrate = $tva_tx . ' (' . $request_data['vat_src_code'] . ')';
1312 }
1313
1314 // Create the discount using Societe::set_remise_except()
1315 $this->db->begin();
1316
1317 $result = $this->company->set_remise_except($amount, DolibarrApiAccess::$user, $description, $vatrate, $discount_type, $price_base_type);
1318
1319 if ($result > 0) {
1320 $this->db->commit();
1321 return $result;
1322 } else {
1323 $this->db->rollback();
1324 throw new RestException(500, 'Error creating discount: '.$this->company->error, array_merge(array($this->company->error), $this->company->errors));
1325 }
1326 }
1327
1351 public function splitdiscount($id, $discountid, $amount_ttc_1, $amount_ttc_2)
1352 {
1353 $obj_ret = array();
1354
1355 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer') || !DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
1356 throw new RestException(403);
1357 }
1358
1359 if (empty($id)) {
1360 throw new RestException(400, 'Thirdparty ID is mandatory');
1361 }
1362 if (empty($discountid)) {
1363 throw new RestException(400, 'Discount ID is mandatory');
1364 }
1365 if (empty($amount_ttc_1) || empty($amount_ttc_2)) {
1366 throw new RestException(400, 'Amount are mandatory');
1367 }
1368
1369 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1370 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1371 }
1372
1373 $result = $this->company->fetch($id);
1374 if (!$result) {
1375 throw new RestException(404, 'Thirdparty not found');
1376 }
1377 require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
1378 $discount = new DiscountAbsolute($this->db);
1379 $res = $discount->fetch($discountid);
1380 if (!($res > 0)) {
1381 throw new RestException(404, 'Discount not found');
1382 }
1383 if ($discount->socid != $id) {
1384 throw new RestException(405, 'Discount not owned by this thirdpartie');
1385 }
1386
1387 if (price2num((float) $amount_ttc_1 + (float) $amount_ttc_2) != $discount->amount_ttc) {
1388 throw new RestException(405, 'Sum of the 2 discounts is different that the original discount');
1389 }
1390 if ($discount->fk_facture_line) {
1391 throw new RestException(409, 'Discount is already used');
1392 }
1393
1394 $newdiscount1 = new DiscountAbsolute($this->db);
1395 $newdiscount2 = new DiscountAbsolute($this->db);
1396
1397 $newdiscount1->fk_facture_source = $discount->fk_facture_source;
1398 $newdiscount2->fk_facture_source = $discount->fk_facture_source;
1399 $newdiscount1->fk_facture = $discount->fk_facture;
1400 $newdiscount2->fk_facture = $discount->fk_facture;
1401 $newdiscount1->fk_facture_line = $discount->fk_facture_line;
1402 $newdiscount2->fk_facture_line = $discount->fk_facture_line;
1403 $newdiscount1->fk_invoice_supplier_source = $discount->fk_invoice_supplier_source;
1404 $newdiscount2->fk_invoice_supplier_source = $discount->fk_invoice_supplier_source;
1405 $newdiscount1->fk_invoice_supplier = $discount->fk_invoice_supplier;
1406 $newdiscount2->fk_invoice_supplier = $discount->fk_invoice_supplier;
1407 $newdiscount1->fk_invoice_supplier_line = $discount->fk_invoice_supplier_line;
1408 $newdiscount2->fk_invoice_supplier_line = $discount->fk_invoice_supplier_line;
1409 if ($discount->description == '(CREDIT_NOTE)' || $discount->description == '(DEPOSIT)') {
1410 $newdiscount1->description = $discount->description;
1411 $newdiscount2->description = $discount->description;
1412 } else {
1413 $newdiscount1->description = $discount->description.' (1)';
1414 $newdiscount2->description = $discount->description.' (2)';
1415 }
1416
1417 $newdiscount1->fk_user = $discount->fk_user;
1418 $newdiscount2->fk_user = $discount->fk_user;
1419 $newdiscount1->fk_soc = $discount->fk_soc;
1420 $newdiscount1->socid = $discount->socid;
1421 $newdiscount2->fk_soc = $discount->fk_soc;
1422 $newdiscount2->socid = $discount->socid;
1423 $newdiscount1->discount_type = $discount->discount_type;
1424 $newdiscount2->discount_type = $discount->discount_type;
1425 $newdiscount1->datec = $discount->datec;
1426 $newdiscount2->datec = $discount->datec;
1427 $newdiscount1->tva_tx = $discount->tva_tx;
1428 $newdiscount2->tva_tx = $discount->tva_tx;
1429 $newdiscount1->vat_src_code = $discount->vat_src_code;
1430 $newdiscount2->vat_src_code = $discount->vat_src_code;
1431 $newdiscount1->amount_ttc = $amount_ttc_1;
1432 $newdiscount2->amount_ttc = price2num($discount->amount_ttc - $newdiscount1->amount_ttc);
1433 $newdiscount1->amount_ht = price2num($newdiscount1->amount_ttc / (1 + $newdiscount1->tva_tx / 100), 'MT');
1434 $newdiscount2->amount_ht = price2num($newdiscount2->amount_ttc / (1 + $newdiscount2->tva_tx / 100), 'MT');
1435 $newdiscount1->amount_tva = price2num($newdiscount1->amount_ttc - $newdiscount1->amount_ht);
1436 $newdiscount2->amount_tva = price2num($newdiscount2->amount_ttc - $newdiscount2->amount_ht);
1437
1438 $newdiscount1->multicurrency_amount_ttc = (float) $amount_ttc_1 * ($discount->multicurrency_amount_ttc / $discount->amount_ttc);
1439 $newdiscount2->multicurrency_amount_ttc = price2num($discount->multicurrency_amount_ttc - $newdiscount1->multicurrency_amount_ttc);
1440 $newdiscount1->multicurrency_amount_ht = price2num($newdiscount1->multicurrency_amount_ttc / (1 + $newdiscount1->tva_tx / 100), 'MT');
1441 $newdiscount2->multicurrency_amount_ht = price2num($newdiscount2->multicurrency_amount_ttc / (1 + $newdiscount2->tva_tx / 100), 'MT');
1442 $newdiscount1->multicurrency_amount_tva = price2num($newdiscount1->multicurrency_amount_ttc - $newdiscount1->multicurrency_amount_ht);
1443 $newdiscount2->multicurrency_amount_tva = price2num($newdiscount2->multicurrency_amount_ttc - $newdiscount2->multicurrency_amount_ht);
1444
1445 // DiscountAbsolute->amount_ttc ->amount_ht ->amount_tva are marked as @deprecated but seems to yet be in use so we fill ->amout_xxx and ->total_xxx
1446 // the same for multicurrency_amount_xxx and multicurrency_total_xxx
1447 $newdiscount1->total_ttc = (float) price2num($newdiscount1->amount_ttc);
1448 $newdiscount1->total_ht = (float) price2num($newdiscount1->amount_ht);
1449 $newdiscount1->total_tva = (float) price2num($newdiscount1->amount_tva);
1450 $newdiscount2->total_ttc = (float) price2num($newdiscount2->amount_ttc);
1451 $newdiscount2->total_ht = (float) price2num($newdiscount2->amount_ht);
1452 $newdiscount2->total_tva = (float) price2num($newdiscount2->amount_tva);
1453 $newdiscount1->multicurrency_total_ttc = (float) price2num($newdiscount1->multicurrency_amount_ttc);
1454 $newdiscount1->multicurrency_total_ht = (float) price2num($newdiscount1->multicurrency_amount_ht);
1455 $newdiscount1->multicurrency_total_tva = (float) price2num($newdiscount1->multicurrency_amount_tva);
1456 $newdiscount2->multicurrency_total_ttc = (float) price2num($newdiscount2->multicurrency_amount_ttc);
1457 $newdiscount2->multicurrency_total_ht = (float) price2num($newdiscount2->multicurrency_amount_ht);
1458 $newdiscount2->multicurrency_total_tva = (float) price2num($newdiscount2->multicurrency_amount_tva);
1459
1460 $this->db->begin();
1461
1462 $discount->fk_facture_source = 0; // This is to delete only the require record (that we will recreate with two records) and not all family with same fk_facture_source
1463 // This is to delete only the require record (that we will recreate with two records) and not all family with same fk_invoice_supplier_source
1464 $discount->fk_invoice_supplier_source = 0;
1465 $res = $discount->delete(DolibarrApiAccess::$user);
1466 $newid1 = $newdiscount1->create(DolibarrApiAccess::$user);
1467 $newid2 = $newdiscount2->create(DolibarrApiAccess::$user);
1468 if ($res <= 0 || $newid1 <= 0 || $newid2 <= 0) {
1469 $this->db->rollback();
1470 throw new RestException(500, 'Operation fail');
1471 }
1472
1473 $this->db->commit();
1474
1475 $sql = "SELECT f.ref, f.type as factype, re.fk_facture_source, re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc, re.description, re.fk_facture, re.fk_facture_line";
1476 $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re, ".MAIN_DB_PREFIX."facture as f";
1477 $sql .= " WHERE re.rowid IN (".((int) $newid1).",".((int) $newid2).") AND f.rowid = re.fk_facture_source AND re.fk_soc = ".((int) $id);
1478
1479 $sql .= $this->db->order("f.type", "ASC");
1480
1481 $result = $this->db->query($sql);
1482 if (!$result) {
1483 throw new RestException(503, $this->db->lasterror());
1484 } else {
1485 // $num = $this->db->num_rows($result);
1486 while ($obj = $this->db->fetch_object($result)) {
1487 $obj_ret[] = $obj;
1488 }
1489 }
1490
1491 return $obj_ret;
1492 }
1493
1494
1513 {
1514 if (!DolibarrApiAccess::$user->hasRight('facture', 'lire')) {
1515 throw new RestException(403);
1516 }
1517 if (empty($id)) {
1518 throw new RestException(400, 'Thirdparty ID is mandatory');
1519 }
1520
1521 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1522 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1523 }
1524
1525 /*$result = $this->thirdparty->fetch($id);
1526 if( ! $result ) {
1527 throw new RestException(404, 'Thirdparty not found');
1528 }*/
1529
1530 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
1531 $invoice = new Facture($this->db);
1532 $result = $invoice->list_replacable_invoices($id);
1533 if ($result < 0) {
1534 throw new RestException(405, $invoice->error);
1535 }
1536
1537 return $result;
1538 }
1539
1562 {
1563 if (!DolibarrApiAccess::$user->hasRight('facture', 'lire')) {
1564 throw new RestException(403);
1565 }
1566 if (empty($id)) {
1567 throw new RestException(400, 'Thirdparty ID is mandatory');
1568 }
1569
1570 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1571 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1572 }
1573
1574 /*$result = $this->thirdparty->fetch($id);
1575 if( ! $result ) {
1576 throw new RestException(404, 'Thirdparty not found');
1577 }*/
1578
1579 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
1580 $invoice = new Facture($this->db);
1581 $result = $invoice->list_qualified_avoir_invoices($id);
1582 if (!is_array($result) && $result < 0) {
1583 throw new RestException(405, $invoice->error);
1584 }
1585
1586 return $result;
1587 }
1588
1605 {
1606 if (empty($id)) {
1607 throw new RestException(400, 'Thirdparty ID is mandatory');
1608 }
1609 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
1610 throw new RestException(403);
1611 }
1612 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1613 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1614 }
1615
1620 $sql = "SELECT rowid as id, fk_action as event, fk_soc as socid, fk_contact as contact_id, type, datec, tms";
1621 $sql .= " FROM ".MAIN_DB_PREFIX."notify_def";
1622 if ($id) {
1623 $sql .= " WHERE fk_soc = ".((int) $id);
1624 }
1625
1626 $result = $this->db->query($sql);
1627 if ($this->db->num_rows($result) == 0) {
1628 throw new RestException(404, 'Notification not found');
1629 }
1630
1631 $i = 0;
1632
1633 $notifications = array();
1634
1635 if ($result) {
1636 $i = 0;
1637 $num = $this->db->num_rows($result);
1638 //$min = min($num, ($limit <= 0 ? $num : $limit));
1639 $min = $num;
1640 while ($i < $min) {
1641 $obj = $this->db->fetch_object($result);
1642 $notifications[] = $obj;
1643 $i++;
1644 }
1645 } else {
1646 throw new RestException(404, 'No notifications found');
1647 }
1648
1649 $fields = array('id', 'socid', 'event', 'contact_id', 'datec', 'tms', 'type');
1650
1651 $returnNotifications = array();
1652
1653 foreach ($notifications as $notification) {
1654 $object = array();
1655 foreach ($notification as $key => $value) {
1656 if (in_array($key, $fields)) {
1657 $object[$key] = $value;
1658 }
1659 }
1660 $returnNotifications[] = $object;
1661 }
1662
1663 // Too complex for phan ?: @phan-suppress-next-line PhanTypeMismatchReturn
1664 return $returnNotifications;
1665 }
1666
1683 public function createCompanyNotification($id, $request_data = null)
1684 {
1685 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
1686 throw new RestException(403, "User has no right to update thirdparties");
1687 }
1688 if ($this->company->fetch($id) <= 0) {
1689 throw new RestException(404, 'Error creating Thirdparty Notification, Thirdparty doesn\'t exists');
1690 }
1691 $notification = new Notify($this->db);
1692
1693 $notification->socid = $id;
1694
1695 foreach ($request_data as $field => $value) {
1696 $notification->$field = $this->_checkValForAPI($field, $value, $notification);
1697 }
1698
1699 $event = $notification->event;
1700 if (!$event) {
1701 throw new RestException(500, 'Error creating Thirdparty Notification, request_data missing event');
1702 }
1703 $socid = $notification->socid;
1704 $contact_id = $notification->contact_id;
1705
1706 $exists_sql = "SELECT rowid, fk_action as event, fk_soc as socid, fk_contact as contact_id, type, datec, tms as datem";
1707 $exists_sql .= " FROM ".MAIN_DB_PREFIX."notify_def";
1708 $exists_sql .= " WHERE fk_action = '".$this->db->escape((string) $event)."'";
1709 $exists_sql .= " AND fk_soc = '".$this->db->escape((string) $socid)."'";
1710 $exists_sql .= " AND fk_contact = '".$this->db->escape((string) $contact_id)."'";
1711
1712 $exists_result = $this->db->query($exists_sql);
1713 if ($this->db->num_rows($exists_result) > 0) {
1714 throw new RestException(403, 'Notification already exists');
1715 }
1716
1717 if ($notification->create(DolibarrApiAccess::$user) < 0) {
1718 throw new RestException(500, 'Error creating Thirdparty Notification');
1719 }
1720
1721 if ($notification->update(DolibarrApiAccess::$user) < 0) {
1722 throw new RestException(500, 'Error updating values');
1723 }
1724
1725 return $this->_cleanObjectDatas($notification);
1726 }
1727
1746 public function createCompanyNotificationByCode($id, $code, $request_data = null)
1747 {
1748 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
1749 throw new RestException(403, "User has no right to update thirdparties");
1750 }
1751 if ($this->company->fetch($id) <= 0) {
1752 throw new RestException(404, 'Error creating Thirdparty Notification, Thirdparty doesn\'t exists');
1753 }
1754 $notification = new Notify($this->db);
1755 $notification->socid = $id;
1756
1757 $sql = "SELECT t.rowid as id FROM ".MAIN_DB_PREFIX."c_action_trigger as t";
1758 $sql .= " WHERE t.code = '".$this->db->escape($code)."'";
1759
1760 $result = $this->db->query($sql);
1761 if ($this->db->num_rows($result) == 0) {
1762 throw new RestException(404, 'Action Trigger code not found');
1763 }
1764
1765 $notification->event = $this->db->fetch_row($result)[0];
1766 foreach ($request_data as $field => $value) {
1767 if ($field === 'event') {
1768 throw new RestException(500, 'Error creating Thirdparty Notification, request_data contains event key');
1769 }
1770 if ($field === 'fk_action') {
1771 throw new RestException(500, 'Error creating Thirdparty Notification, request_data contains fk_action key');
1772 }
1773 $notification->$field = $this->_checkValForAPI($field, $value, $notification);
1774 }
1775
1776 $event = $notification->event;
1777 $socid = $notification->socid;
1778 $contact_id = $notification->contact_id;
1779
1780 $exists_sql = "SELECT rowid, fk_action as event, fk_soc as socid, fk_contact as contact_id, type, datec, tms as datem";
1781 $exists_sql .= " FROM ".MAIN_DB_PREFIX."notify_def";
1782 $exists_sql .= " WHERE fk_action = '".$this->db->escape((string) $event)."'";
1783 $exists_sql .= " AND fk_soc = '".$this->db->escape((string) $socid)."'";
1784 $exists_sql .= " AND fk_contact = '".$this->db->escape((string) $contact_id)."'";
1785
1786 $exists_result = $this->db->query($exists_sql);
1787 if ($this->db->num_rows($exists_result) > 0) {
1788 throw new RestException(403, 'Notification already exists');
1789 }
1790
1791 if ($notification->create(DolibarrApiAccess::$user) < 0) {
1792 throw new RestException(500, 'Error creating Thirdparty Notification, are request_data well formed?');
1793 }
1794
1795 if ($notification->update(DolibarrApiAccess::$user) < 0) {
1796 throw new RestException(500, 'Error updating values');
1797 }
1798
1799 return $this->_cleanObjectDatas($notification);
1800 }
1801
1816 public function deleteCompanyNotification($id, $notification_id)
1817 {
1818 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
1819 throw new RestException(403);
1820 }
1821
1822 $notification = new Notify($this->db);
1823
1824 $notification->fetch($notification_id);
1825
1826 $socid = (int) $notification->socid;
1827
1828 if ($socid == $id) {
1829 return $notification->delete(DolibarrApiAccess::$user);
1830 } else {
1831 throw new RestException(403, "Not allowed due to bad consistency of input data");
1832 }
1833 }
1834
1852 public function updateCompanyNotification($id, $notification_id, $request_data = null)
1853 {
1854 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
1855 throw new RestException(403, "User has no right to update thirdparties");
1856 }
1857 if ($this->company->fetch($id) <= 0) {
1858 throw new RestException(404, 'Error creating Company Notification, Company doesn\'t exists');
1859 }
1860 $notification = new Notify($this->db);
1861
1862 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
1863 $notification->fetch($notification_id, $id);
1864
1865 if ($notification->socid != $id) {
1866 throw new RestException(403, "Not allowed due to bad consistency of input data");
1867 }
1868
1869 foreach ($request_data as $field => $value) {
1870 $notification->$field = $this->_checkValForAPI($field, $value, $notification);
1871 }
1872
1873 if ($notification->update(DolibarrApiAccess::$user) < 0) {
1874 throw new RestException(500, 'Error updating values');
1875 }
1876
1877 return $this->_cleanObjectDatas($notification);
1878 }
1879
1896 {
1897 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
1898 throw new RestException(403);
1899 }
1900 if (empty($id)) {
1901 throw new RestException(400, 'Thirdparty ID is mandatory');
1902 }
1903
1904 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1905 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1906 }
1907
1912 $sql = "SELECT rowid, fk_soc, bank, number, code_banque, code_guichet, cle_rib, bic, iban_prefix as iban, domiciliation as address, proprio,";
1913 $sql .= " owner_address, default_rib, label, datec, tms as datem, rum, frstrecur";
1914 $sql .= " FROM ".MAIN_DB_PREFIX."societe_rib";
1915 if ($id) {
1916 $sql .= " WHERE fk_soc = ".((int) $id);
1917 }
1918
1919 $result = $this->db->query($sql);
1920
1921 if ($this->db->num_rows($result) == 0) {
1922 throw new RestException(404, 'Account not found');
1923 }
1924
1925 $i = 0;
1926
1927 $accounts = array();
1928
1929 if ($result) {
1930 $i = 0;
1931 $num = $this->db->num_rows($result);
1932 //$min = min($num, ($limit <= 0 ? $num : $limit));
1933 $min = $num;
1934 while ($i < $min) {
1935 $obj = $this->db->fetch_object($result);
1936
1937 $account = new CompanyBankAccount($this->db);
1938 if ($account->fetch($obj->rowid)) {
1939 $accounts[] = $account;
1940 }
1941 $i++;
1942 }
1943 } else {
1944 throw new RestException(404, 'Account not found');
1945 }
1946
1947
1948 $fields = array('socid', 'default_rib', 'frstrecur', '1000110000001', 'datec', 'datem', 'label', 'bank', 'bic', 'iban', 'id', 'rum');
1949
1950 $returnAccounts = array();
1951
1952 foreach ($accounts as $account) {
1953 $object = array();
1954 foreach ($account as $key => $value) {
1955 if (in_array($key, $fields)) {
1956 if ($key == 'iban') {
1957 $object[$key] = dolDecrypt($value);
1958 } else {
1959 $object[$key] = $value;
1960 }
1961 }
1962 }
1963 $returnAccounts[] = $object;
1964 }
1965
1966 return $returnAccounts;
1967 }
1968
1985 public function createCompanyBankAccount($id, $request_data = null)
1986 {
1987 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
1988 throw new RestException(403);
1989 }
1990 if ($this->company->fetch($id) <= 0) {
1991 throw new RestException(404, 'Error creating Company Bank account, Company doesn\'t exists');
1992 }
1993 $account = new CompanyBankAccount($this->db);
1994
1995 $account->socid = $id;
1996
1997 foreach ($request_data as $field => $value) {
1998 if ($field === 'caller') {
1999 // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
2000 $this->company->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
2001 continue;
2002 }
2003
2004 $account->$field = $this->_checkValForAPI('extrafields', $value, $account);
2005 }
2006
2007 if ($account->create(DolibarrApiAccess::$user) < 0) {
2008 throw new RestException(500, 'Error creating Company Bank account');
2009 }
2010
2011 if (empty($account->rum)) {
2012 require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php';
2013 $prelevement = new BonPrelevement($this->db);
2014 $account->rum = $prelevement->buildRumNumber((string) $this->company->code_client, $account->datec, (string) $account->id);
2015 $account->date_rum = dol_now();
2016 }
2017
2018 if ($account->update(DolibarrApiAccess::$user) < 0) {
2019 throw new RestException(500, 'Error updating values');
2020 }
2021
2022 return $this->_cleanObjectDatas($account);
2023 }
2024
2042 public function updateCompanyBankAccount($id, $bankaccount_id, $request_data = null)
2043 {
2044 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2045 throw new RestException(403);
2046 }
2047 if ($this->company->fetch($id) <= 0) {
2048 throw new RestException(404, 'Error creating Company Bank account, Company doesn\'t exists');
2049 }
2050 $account = new CompanyBankAccount($this->db);
2051
2052 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
2053 $account->fetch($bankaccount_id, '', $id, -1, '');
2054
2055 if ($account->socid != $id) {
2056 throw new RestException(403);
2057 }
2058
2059
2060 foreach ($request_data as $field => $value) {
2061 if ($field === 'caller') {
2062 // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
2063 $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
2064 continue;
2065 }
2066
2067 $account->$field = $this->_checkValForAPI($field, $value, $account);
2068 }
2069
2070 if (empty($account->rum)) {
2071 require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php';
2072 $prelevement = new BonPrelevement($this->db);
2073 $account->rum = $prelevement->buildRumNumber((string) $this->company->code_client, $account->datec, (string) $account->id);
2074 $account->date_rum = dol_now();
2075 }
2076
2077 if ($account->update(DolibarrApiAccess::$user) < 0) {
2078 throw new RestException(500, 'Error updating values');
2079 }
2080
2081 return $this->_cleanObjectDatas($account);
2082 }
2083
2098 public function deleteCompanyBankAccount($id, $bankaccount_id)
2099 {
2100 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2101 throw new RestException(403);
2102 }
2103
2104 $account = new CompanyBankAccount($this->db);
2105
2106 $account->fetch($bankaccount_id);
2107
2108 $socid = (int) $account->socid;
2109
2110 if ($socid == $id) {
2111 return $account->delete(DolibarrApiAccess::$user);
2112 } else {
2113 throw new RestException(403, "Not allowed due to bad consistency of input data");
2114 }
2115 }
2116
2135 public function generateBankAccountDocument($id, $companybankid = null, $model = 'sepamandate')
2136 {
2137 global $conf, $langs;
2138
2139 $langs->loadLangs(array("main", "dict", "commercial", "products", "companies", "banks", "bills", "withdrawals"));
2140
2141 if ($this->company->fetch($id) <= 0) {
2142 throw new RestException(404, 'Thirdparty not found');
2143 }
2144
2145 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2146 throw new RestException(403);
2147 }
2148
2149 $this->company->setDocModel(DolibarrApiAccess::$user, $model);
2150
2151 $this->company->fk_bank = $this->company->fk_account;
2152 // $this->company->fk_account = $this->company->fk_account;
2153
2154 $outputlangs = $langs;
2155 $newlang = '';
2156
2157 //if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) $newlang = GETPOST('lang_id', 'aZ09');
2158 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
2159 if (isset($this->company->thirdparty->default_lang)) {
2160 $newlang = $this->company->thirdparty->default_lang; // for proposal, order, invoice, ...
2161 } elseif (isset($this->company->default_lang)) {
2162 $newlang = $this->company->default_lang; // for thirdparty
2163 }
2164 }
2165 if (!empty($newlang)) {
2166 $outputlangs = new Translate("", $conf);
2167 $outputlangs->setDefaultLang($newlang);
2168 }
2169
2170 $sql = "SELECT rowid";
2171 $sql .= " FROM ".MAIN_DB_PREFIX."societe_rib";
2172 if ($id) {
2173 $sql .= " WHERE fk_soc = ".((int) $id);
2174 }
2175 if ($companybankid) {
2176 $sql .= " AND rowid = ".((int) $companybankid);
2177 }
2178
2179 $i = 0;
2180 $accounts = array();
2181
2182 $result = $this->db->query($sql);
2183 if ($result) {
2184 if ($this->db->num_rows($result) == 0) {
2185 throw new RestException(404, 'Bank account not found');
2186 }
2187
2188 $num = $this->db->num_rows($result);
2189 //$min = min($num, ($limit <= 0 ? $num : $limit));
2190 $min = $num;
2191 while ($i < $min) {
2192 $obj = $this->db->fetch_object($result);
2193
2194 $account = new CompanyBankAccount($this->db);
2195 if ($account->fetch($obj->rowid)) {
2196 $accounts[] = $account;
2197 }
2198 $i++;
2199 }
2200 } else {
2201 throw new RestException(500, 'Sql error '.$this->db->lasterror());
2202 }
2203
2204 $moreparams = array(
2205 'use_companybankid' => $accounts[0]->id,
2206 'force_dir_output' => $conf->societe->multidir_output[$this->company->entity].'/'.dol_sanitizeFileName((string) $this->company->id)
2207 );
2208
2209 $result = $this->company->generateDocument($model, $outputlangs, 0, 0, 0, $moreparams);
2210
2211 if ($result > 0) {
2212 return array("success" => $result);
2213 } else {
2214 throw new RestException(500, 'Error generating the document '.$this->company->error);
2215 }
2216 }
2217
2235 public function getSocieteAccounts($id, $site = null)
2236 {
2237 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
2238 throw new RestException(403);
2239 }
2240
2241 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
2242 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
2243 }
2244
2248 $sql = "SELECT rowid, fk_soc, key_account, site, date_creation, tms FROM ".MAIN_DB_PREFIX."societe_account";
2249 $sql .= " WHERE fk_soc = ".((int) $id);
2250 if ($site) {
2251 $sql .= " AND site ='".$this->db->escape($site)."'";
2252 }
2253
2254 $result = $this->db->query($sql);
2255
2256 if ($result && $this->db->num_rows($result) == 0) {
2257 throw new RestException(404, 'This thirdparty does not have any account attached or does not exist.');
2258 }
2259
2260 $i = 0;
2261
2262 $accounts = array();
2263
2264 $i = 0;
2265 $num = $this->db->num_rows($result);
2266 //$min = min($num, ($limit <= 0 ? $num : $limit));
2267 $min = $num;
2268 while ($i < $min) {
2269 $obj = $this->db->fetch_object($result);
2270 $account = new SocieteAccount($this->db);
2271
2272 if ($account->fetch($obj->rowid)) {
2273 $accounts[] = $account;
2274 }
2275 $i++;
2276 }
2277
2278 $fields = array('id', 'fk_soc', 'key_account', 'site', 'date_creation', 'tms');
2279
2280 $returnAccounts = array();
2281
2282 foreach ($accounts as $account) {
2283 $object = array();
2284 foreach ($account as $key => $value) {
2285 if (in_array($key, $fields)) {
2286 $object[$key] = $value;
2287 }
2288 }
2289 $returnAccounts[] = $object;
2290 }
2291
2292 return $returnAccounts;
2293 }
2294
2312 public function getSocieteByAccounts($site, $key_account)
2313 {
2314 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
2315 throw new RestException(403);
2316 }
2317
2318 $sql = "SELECT rowid, fk_soc, key_account, site, date_creation, tms FROM ".MAIN_DB_PREFIX."societe_account";
2319 $sql .= " WHERE site = '".$this->db->escape($site)."' AND key_account = '".$this->db->escape($key_account)."'";
2320 $sql .= " AND entity IN (".getEntity('societe').")";
2321
2322 $result = $this->db->query($sql);
2323
2324 if ($result && $this->db->num_rows($result) == 1) {
2325 $obj = $this->db->fetch_object($result);
2326 $returnThirdparty = $this->_fetch($obj->fk_soc);
2327 } else {
2328 throw new RestException(404, 'This account have many thirdparties attached or does not exist.');
2329 }
2330
2331 if (!DolibarrApi::_checkAccessToResource('societe', $returnThirdparty->id)) {
2332 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
2333 }
2334
2335 return $returnThirdparty;
2336 }
2337
2361 public function createSocieteAccount($id, $request_data = null)
2362 {
2363 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2364 throw new RestException(403);
2365 }
2366
2367 if (!isset($request_data['site'])) {
2368 throw new RestException(422, 'Unprocessable Entity: You must pass the site attribute in your request data !');
2369 }
2370
2371 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = ".((int) $id)." AND site = '".$this->db->escape($request_data['site'])."'";
2372 $result = $this->db->query($sql);
2373
2374 if ($result && $this->db->num_rows($result) == 0) {
2375 $account = new SocieteAccount($this->db);
2376 if (!isset($request_data['login'])) {
2377 $account->login = "";
2378 }
2379 $account->fk_soc = $id;
2380
2381 foreach ($request_data as $field => $value) {
2382 if ($field === 'caller') {
2383 // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
2384 $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
2385 continue;
2386 }
2387
2388 $account->$field = $this->_checkValForAPI($field, $value, $account);
2389 }
2390
2391 if ($account->create(DolibarrApiAccess::$user) < 0) {
2392 throw new RestException(500, 'Error creating SocieteAccount entity. Ensure that the ID of thirdparty provided does exist!');
2393 }
2394
2395 $this->_cleanObjectDatas($account);
2396
2397 return $account;
2398 } else {
2399 throw new RestException(409, 'A SocieteAccount entity already exists for this company and site.');
2400 }
2401 }
2402
2429 public function postSocieteAccount($id, $site, $request_data = null)
2430 {
2431 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2432 throw new RestException(403);
2433 }
2434
2435 $sql = "SELECT rowid, fk_user_creat, date_creation FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = ".((int) $id)." AND site = '".$this->db->escape($site)."'";
2436 $result = $this->db->query($sql);
2437
2438 // We do not found an existing SocieteAccount entity for this fk_soc and site ; we then create a new one.
2439 if ($result && $this->db->num_rows($result) == 0) {
2440 if (!isset($request_data['key_account'])) {
2441 throw new RestException(422, 'Unprocessable Entity: You must pass the key_account attribute in your request data !');
2442 }
2443 $account = new SocieteAccount($this->db);
2444 if (!isset($request_data['login'])) {
2445 $account->login = "";
2446 }
2447
2448 foreach ($request_data as $field => $value) {
2449 if ($field === 'caller') {
2450 // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
2451 $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
2452 continue;
2453 }
2454
2455 $account->$field = $this->_checkValForAPI($field, $value, $account);
2456 }
2457
2458 $account->fk_soc = $id;
2459 $account->site = $site;
2460
2461 if ($account->create(DolibarrApiAccess::$user) < 0) {
2462 throw new RestException(500, 'Error creating SocieteAccount entity.');
2463 }
2464 // We found an existing SocieteAccount entity, we are replacing it
2465 } else {
2466 if (isset($request_data['site']) && $request_data['site'] !== $site) {
2467 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = ".((int) $id)." AND site = '".$this->db->escape($request_data['site'])."' ";
2468 $result = $this->db->query($sql);
2469
2470 if ($result && $this->db->num_rows($result) !== 0) {
2471 throw new RestException(409, "You are trying to update this thirdparty Account for $site to ".$request_data['site']." but another Account already exists with this site key.");
2472 }
2473 }
2474
2475 $obj = $this->db->fetch_object($result);
2476
2477 $account = new SocieteAccount($this->db);
2478 $account->id = $obj->rowid;
2479 $account->fk_soc = $id;
2480 $account->site = $site;
2481 if (!isset($request_data['login'])) {
2482 $account->login = "";
2483 }
2484 $account->fk_user_creat = $obj->fk_user_creat;
2485 $account->date_creation = $obj->date_creation;
2486
2487 foreach ($request_data as $field => $value) {
2488 if ($field === 'caller') {
2489 // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
2490 $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
2491 continue;
2492 }
2493
2494 $account->$field = $this->_checkValForAPI($field, $value, $account);
2495 }
2496
2497 if ($account->update(DolibarrApiAccess::$user) < 0) {
2498 throw new RestException(500, 'Error updating SocieteAccount entity.');
2499 }
2500 }
2501
2502 $this->_cleanObjectDatas($account);
2503
2504 return $account;
2505 }
2506
2527 public function putSocieteAccount($id, $site, $request_data = null)
2528 {
2529 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2530 throw new RestException(403);
2531 }
2532
2533 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = ".((int) $id)." AND site = '".$this->db->escape($site)."'";
2534 $result = $this->db->query($sql);
2535
2536 if ($result && $this->db->num_rows($result) == 0) {
2537 throw new RestException(404, "This thirdparty does not have $site account attached or does not exist.");
2538 } else {
2539 // If the user tries to edit the site member, we check first if
2540 if (isset($request_data['site']) && $request_data['site'] !== $site) {
2541 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = ".((int) $id)." AND site = '".$this->db->escape($request_data['site'])."' ";
2542 $result = $this->db->query($sql);
2543
2544 if ($result && $this->db->num_rows($result) !== 0) {
2545 throw new RestException(409, "You are trying to update this thirdparty Account for ".$site." to ".$request_data['site']." but another Account already exists for this thirdparty with this site key.");
2546 }
2547 }
2548
2549 $obj = $this->db->fetch_object($result);
2550 $account = new SocieteAccount($this->db);
2551 $account->fetch($obj->rowid);
2552
2553 foreach ($request_data as $field => $value) {
2554 if ($field === 'caller') {
2555 // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
2556 $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
2557 continue;
2558 }
2559
2560 $account->$field = $this->_checkValForAPI($field, $value, $account);
2561 }
2562
2563 if ($account->update(DolibarrApiAccess::$user) < 0) {
2564 throw new RestException(500, 'Error updating SocieteAccount account');
2565 }
2566
2567 $this->_cleanObjectDatas($account);
2568
2569 return $account;
2570 }
2571 }
2572
2591 public function deleteSocieteAccount($id, $site)
2592 {
2593 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2594 throw new RestException(403);
2595 }
2596
2597 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = ".((int) $id)." AND site = '".$this->db->escape($site)."'";
2598 $result = $this->db->query($sql);
2599
2600 if ($result && $this->db->num_rows($result) == 0) {
2601 throw new RestException(404);
2602 } else {
2603 $obj = $this->db->fetch_object($result);
2604 $account = new SocieteAccount($this->db);
2605 $account->fetch($obj->rowid);
2606
2607 if ($account->delete(DolibarrApiAccess::$user) < 0) {
2608 throw new RestException(500, "Error while deleting $site account attached to this third party");
2609 }
2610 }
2611 }
2612
2629 {
2630 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2631 throw new RestException(403);
2632 }
2633
2638 $sql = "SELECT rowid, fk_soc, key_account, site, date_creation, tms";
2639 $sql .= " FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = ".((int) $id);
2640
2641 $result = $this->db->query($sql);
2642
2643 if ($result && $this->db->num_rows($result) == 0) {
2644 throw new RestException(404, 'This third party does not have any account attached or does not exist.');
2645 } else {
2646 $i = 0;
2647
2648 $i = 0;
2649 $num = $this->db->num_rows($result);
2650 //$min = min($num, ($limit <= 0 ? $num : $limit));
2651 $min = $num;
2652 while ($i < $min) {
2653 $obj = $this->db->fetch_object($result);
2654 $account = new SocieteAccount($this->db);
2655 $account->fetch($obj->rowid);
2656
2657 if ($account->delete(DolibarrApiAccess::$user) < 0) {
2658 throw new RestException(500, 'Error while deleting account attached to this third party');
2659 }
2660 $i++;
2661 }
2662 }
2663 }
2664
2665 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2675 protected function _cleanObjectDatas($object)
2676 {
2677 // phpcs:enable
2678 $object = parent::_cleanObjectDatas($object);
2679
2680 unset($object->nom); // ->name already defined and nom deprecated
2681 unset($object->name_bis); // ->name_alias already defined
2682 unset($object->note); // ->note_private and note_public already defined
2683 unset($object->departement);
2684 unset($object->departement_code);
2685 unset($object->pays);
2686 unset($object->particulier);
2687 unset($object->prefix_comm);
2688
2689 unset($object->siren);
2690 unset($object->siret);
2691 unset($object->ape);
2692
2693 unset($object->commercial_id); // This property is used in create/update only. It does not exists in read mode because there is several sales representatives.
2694
2695 unset($object->total_ht);
2696 unset($object->total_tva);
2697 unset($object->total_localtax1);
2698 unset($object->total_localtax2);
2699 unset($object->total_ttc);
2700
2701 unset($object->lines);
2702 unset($object->thirdparty);
2703
2704 unset($object->fk_delivery_address); // deprecated feature
2705
2706 return $object;
2707 }
2708
2717 private function _validate($data)
2718 {
2719 if ($data === null) {
2720 $data = array();
2721 }
2722 $thirdparty = array();
2723 foreach (Thirdparties::$FIELDS as $field) {
2724 if (!isset($data[$field])) {
2725 throw new RestException(400, "$field field missing");
2726 }
2727 $thirdparty[$field] = $data[$field];
2728 }
2729 return $thirdparty;
2730 }
2731
2755 private function _fetch($rowid, $ref = '', $ref_ext = '', $barcode = '', $idprof1 = '', $idprof2 = '', $idprof3 = '', $idprof4 = '', $idprof5 = '', $idprof6 = '', $email = '', $ref_alias = '')
2756 {
2757 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
2758 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login.'. No read permission on thirdparties.');
2759 }
2760
2761 if ($rowid === 0) {
2762 $result = $this->company->initAsSpecimen();
2763 } else {
2764 $result = $this->company->fetch((int) $rowid, $ref, $ref_ext, $barcode, $idprof1, $idprof2, $idprof3, $idprof4, $idprof5, $idprof6, $email, $ref_alias);
2765 }
2766 if (!$result) {
2767 throw new RestException(404, 'Thirdparty not found');
2768 }
2769
2770 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
2771 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login.' on this thirdparty');
2772 }
2773 if (isModEnabled('mailing')) {
2774 $this->company->getNoEmail();
2775 }
2776
2777 if (getDolGlobalString('FACTURE_DEPOSITS_ARE_JUST_PAYMENTS')) {
2778 $filterabsolutediscount = "fk_facture_source IS NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
2779 $filtercreditnote = "fk_facture_source IS NOT NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
2780 } else {
2781 $filterabsolutediscount = "fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')";
2782 $filtercreditnote = "fk_facture_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%')";
2783 }
2784
2785 $absolute_discount = $this->company->getAvailableDiscounts(null, $filterabsolutediscount);
2786 $absolute_creditnote = $this->company->getAvailableDiscounts(null, $filtercreditnote);
2787 $this->company->absolute_discount = price2num($absolute_discount, 'MT');
2788 $this->company->absolute_creditnote = price2num($absolute_creditnote, 'MT');
2789
2790 return $this->_cleanObjectDatas($this->company);
2791 }
2792}
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
Class to manage withdrawal receipts.
Class to manage categories.
Class to manage bank accounts description of third parties.
Class to manage absolute discounts.
Class for API REST v1.
Definition api.class.php:35
_checkValExtrafieldsForAPI($field, $value, $object)
Check and convert a string depending on its type/name.
_filterObjectProperties($object, $properties)
Filter properties that will be returned on object.
static _checkAccessToResource($resource, $resource_id=0, $dbtablename='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid')
Check access by user to a given resource.
_checkValForAPI($field, $value, $object)
Check and convert a string depending on its type/name.
Class to manage invoices.
Class to manage the table of subscription to notifications.
Class for SocieteAccount.
Class to manage third parties objects (customers, suppliers, prospects...)
updateCompanyNotification($id, $notification_id, $request_data=null)
Update a company notification for a third party.
setThirdpartyPriceLevel($id, $priceLevel)
Set a new price level for the given third party.
_cleanObjectDatas($object)
Clean sensible object datas @phpstan-template T.
getSocieteByAccounts($site, $key_account)
Get a specific third party by account.
getSupplierCategories($id, $sortfield="s.rowid", $sortorder='ASC', $limit=0, $page=0)
Get supplier categories for a third party.
deleteCompanyNotification($id, $notification_id)
Delete a company notification attached to a third party.
getSocieteAccounts($id, $site=null)
Get a specific account attached to a third party.
getOutStandingOrder($id, $mode='customer')
Get outstanding orders for a third party.
addRepresentative($id, $representative_id)
Add a customer representative to a third party.
getByBarcode($barcode)
Get a third party by barcode.
generateBankAccountDocument($id, $companybankid=null, $model='sepamandate')
Generate a document from a bank account record.
createCompanyNotificationByCode($id, $code, $request_data=null)
Create a company notification for a third party using action trigger code.
getCompanyNotification($id)
Get company notifications for a third party.
addCategory($id, $category_id)
Add a customer category to a third party.
getCompanyBankAccount($id)
Get company bank accounts of a third party.
getInvoicesQualifiedForReplacement($id)
Return invoices qualified to be replaced by another invoice.
post($request_data=null)
Create a third party.
put($id, $request_data=null)
Update third party.
getByEmail($email)
Get properties of a third party by email.
_validate($data)
Validate fields before create or update object.
getFixedAmountDiscounts($id, $mode='customer', $filter="none", $sortfield="f.type", $sortorder='ASC')
Get fixed amount discount of a third party.
addSupplierCategory($id, $category_id)
Add a supplier category to a third party.
merge($id, $idtodelete)
Merge a third party into another third party.
deleteSocieteAccounts($id)
Delete all accounts attached to a third party.
__construct()
Constructor.
getCategories($id, $sortfield="s.rowid", $sortorder='ASC', $limit=0, $page=0)
Get customer categories for a third party.
postSocieteAccount($id, $site, $request_data=null)
Create and attach a new (or replace an existing) specific site account for a third party.
deleteSupplierCategory($id, $category_id)
Remove the link between a category and the third party.
createFixedAmountDiscount($id, $request_data=null)
Create a fixed amount discount for a thirdparty.
deleteRepresentative($id, $representative_id)
Remove the link between a customer representative and a third party.
createCompanyNotification($id, $request_data=null)
Create a company notification for a third party.
putSocieteAccount($id, $site, $request_data=null)
Update specified values of a specific account attached to a third party.
updateCompanyBankAccount($id, $bankaccount_id, $request_data=null)
Update a company bank account of a third party.
deleteSocieteAccount($id, $site)
Delete a specific site account attached to a third party.
getInvoicesQualifiedForCreditNote($id)
Return invoices qualified to be corrected by a credit note.
getOutStandingProposals($id, $mode='customer')
Get outstanding proposals for a third party.
_fetch($rowid, $ref='', $ref_ext='', $barcode='', $idprof1='', $idprof2='', $idprof3='', $idprof4='', $idprof5='', $idprof6='', $email='', $ref_alias='')
Fetch properties of a thirdparty object.
getSalesRepresentatives($id, $mode=0)
Get representatives of a third party.
getOutStandingInvoices($id, $mode='customer')
Get outstanding invoices for a third party.
splitdiscount($id, $discountid, $amount_ttc_1, $amount_ttc_2)
Split a discount in 2 smaller discount.
index($sortfield="t.rowid", $sortorder='ASC', $limit=100, $page=0, $mode=0, $category=0, $sqlfilters='', $properties='', $pagination_data=false)
List third parties.
deleteCompanyBankAccount($id, $bankaccount_id)
Delete a bank account attached to a third party.
createSocieteAccount($id, $request_data=null)
Create and attach a new account to an existing third party.
createCompanyBankAccount($id, $request_data=null)
Create a company bank account for a third party.
deleteCategory($id, $category_id)
Remove the link between a customer category and the third party.
Class to manage translations.
Class to manage Dolibarr users.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
dol_now($mode='gmt')
Return date for now.
dol_getIdFromCode($db, $key, $tablename, $fieldkey='code', $fieldid='id', $entityfilter=0, $filters='', $useCache=true)
Return an id or code from a code or id.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
forgeSQLFromUniversalSearchCriteria($filter, &$errorstr='', $noand=0, $nopar=0, $noerror=0)
forgeSQLFromUniversalSearchCriteria
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
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.
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php
dolDecrypt($chain, $key='', $patterntotest='')
Decode a string with a symmetric encryption.