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 * Copyright (C) 2026 Noé Cendrier <noe.cendrier@altairis.fr>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program. If not, see <https://www.gnu.org/licenses/>.
26 */
27
28use Luracast\Restler\RestException;
29
30require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
31
41{
45 public static $FIELDS = array(
46 'name'
47 );
48
52 public $company;
53
57 public function __construct()
58 {
59 global $db;
60 $this->db = $db;
61
62 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
63 require_once DOL_DOCUMENT_ROOT.'/societe/class/societeaccount.class.php';
64 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
65 require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php';
66 require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
67
68 $this->company = new Societe($this->db);
69
70 if (getDolGlobalString('SOCIETE_EMAIL_MANDATORY')) {
71 static::$FIELDS[] = 'email';
72 }
73 }
74
87 public function get($id)
88 {
89 return $this->_fetch($id);
90 }
91
108 public function getByEmail($email)
109 {
110 return $this->_fetch(null, '', '', '', '', '', '', '', '', '', $email);
111 }
112
127 public function getByBarcode($barcode)
128 {
129 return $this->_fetch(null, '', '', $barcode);
130 }
131
158 public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $mode = 0, $category = 0, $sqlfilters = '', $properties = '', $pagination_data = false)
159 {
160 $obj_ret = array();
161
162 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
163 throw new RestException(403);
164 }
165
166 // case of external user, we force socids
167 $socids = DolibarrApiAccess::$user->socid ? (string) DolibarrApiAccess::$user->socid : '';
168
169 // If the internal user must only see his customers, force searching by him
170 $search_sale = 0;
171 if (!DolibarrApiAccess::$user->hasRight('societe', 'client', 'voir') && !$socids) {
172 $search_sale = DolibarrApiAccess::$user->id;
173 }
174
175 $sql = "SELECT t.rowid";
176 $sql .= " FROM ".MAIN_DB_PREFIX."societe as t";
177 $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
178 if ($category > 0) {
179 if ($mode != 4) {
180 $sql .= ", ".MAIN_DB_PREFIX."categorie_societe as c";
181 }
182 if (!in_array($mode, array(1, 2, 3))) {
183 $sql .= ", ".MAIN_DB_PREFIX."categorie_fournisseur as cc";
184 }
185 }
186 $sql .= " WHERE t.entity IN (".getEntity('societe').")";
187 if ($mode == 1) {
188 $sql .= " AND t.client IN (1, 3)";
189 } elseif ($mode == 2) {
190 $sql .= " AND t.client IN (2, 3)";
191 } elseif ($mode == 3) {
192 $sql .= " AND t.client IN (0)";
193 } elseif ($mode == 4) {
194 $sql .= " AND t.fournisseur IN (1)";
195 }
196 // Select third parties of a given category
197 if ($category > 0) {
198 if (!empty($mode) && $mode != 4) {
199 $sql .= " AND c.fk_categorie = ".((int) $category)." AND c.fk_soc = t.rowid";
200 } elseif (!empty($mode) && $mode == 4) {
201 $sql .= " AND cc.fk_categorie = ".((int) $category)." AND cc.fk_soc = t.rowid";
202 } else {
203 $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))";
204 }
205 }
206 if ($socids) {
207 $sql .= " AND t.rowid IN (".$this->db->sanitize($socids).")";
208 }
209 // Search on sale representative
210 if ($search_sale && $search_sale != '-1') {
211 if ($search_sale == -2) {
212 $sql .= " AND ".getSalesRepresentativeSqlFilter('t.rowid', 0, 1);
213 } elseif ($search_sale > 0) {
214 $sql .= " AND ".getSalesRepresentativeSqlFilter('t.rowid', (int) $search_sale);
215 }
216 }
217 // Add sql filters
218 if ($sqlfilters) {
219 $errormessage = '';
220 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
221 if ($errormessage) {
222 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
223 }
224 }
225
226 //this query will return total thirdparties with the filters given
227 $sqlTotals = str_replace('SELECT t.rowid', 'SELECT count(t.rowid) as total', $sql);
228
229 $sql .= $this->db->order($sortfield, $sortorder);
230 if ($limit) {
231 if ($page < 0) {
232 $page = 0;
233 }
234 $offset = $limit * $page;
235
236 $sql .= $this->db->plimit($limit + 1, $offset);
237 }
238
239 $result = $this->db->query($sql);
240 if ($result) {
241 $num = $this->db->num_rows($result);
242 $min = min($num, ($limit <= 0 ? $num : $limit));
243 $i = 0;
244 while ($i < $min) {
245 $obj = $this->db->fetch_object($result);
246 $soc_static = new Societe($this->db);
247 if ($soc_static->fetch($obj->rowid)) {
248 if (isModEnabled('mailing')) {
249 $soc_static->getNoEmail();
250 }
251 $obj_ret[] = $this->_filterObjectProperties($this->_cleanObjectDatas($soc_static), $properties);
252 }
253 $i++;
254 }
255 } else {
256 throw new RestException(503, 'Error when retrieve third parties : '.$this->db->lasterror());
257 }
258 if (!count($obj_ret)) {
259 $message = '';
260 switch ($mode) {
261 case 0:
262 $message = 'No third parties found';
263 break;
264 case 1:
265 $message = 'No customers found';
266 break;
267 case 2:
268 $message = 'No prospects found';
269 break;
270 case 3:
271 $message = 'No other third parties found';
272 break;
273 case 4:
274 $message = 'No suppliers found';
275 }
276 throw new RestException(404, $message);
277 }
278
279 //if $pagination_data is true, the response will contain element data with all values and element pagination with pagination data(total,page,limit)
280 if ($pagination_data) {
281 $totalsResult = $this->db->query($sqlTotals);
282 $total = $this->db->fetch_object($totalsResult)->total;
283
284 $tmp = $obj_ret;
285 $obj_ret = [];
286
287 $obj_ret['data'] = $tmp;
288 $obj_ret['pagination'] = [
289 'total' => (int) $total,
290 'page' => $page, //count starts from 0
291 'page_count' => ceil((int) $total / $limit),
292 'limit' => $limit
293 ];
294 }
295
296 return $obj_ret;
297 }
298
311 public function post($request_data = null)
312 {
313 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
314 throw new RestException(403);
315 }
316
317 // External api user does not know internal country ID
318 if (!isset($request_data['country_id']) && isset($request_data['country_code'])) {
319 $field = strlen($request_data['country_code']) > 2 ? 'code_iso' : 'code';
320 $id = dol_getIdFromCode($this->db, $request_data['country_code'], "c_country", $field, "rowid");
321 if ($id < 0) {
322 throw new RestException(404, 'Country code not found in database: ' . $this->db->error);
323 }
324 $request_data['country_id'] = $id;
325 }
326
327 // Check mandatory fields
328 $result = $this->_validate($request_data);
329
330 foreach ($request_data as $field => $value) {
331 if ($field === 'caller') {
332 // 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
333 $this->company->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
334 continue;
335 }
336 if ($field == 'array_options' && is_array($value)) {
337 $this->company->fetch_optionals(); // To force the load of the extrafields definition by fetch_name_optionals_label()
338
339 foreach ($value as $index => $val) {
340 $this->company->array_options[$index] = $this->_checkValExtrafieldsForAPI($index, $val, $this->company);
341 }
342 continue;
343 }
344
345 $this->company->$field = $this->_checkValForAPI($field, $value, $this->company);
346 }
347
348 if ($this->company->create(DolibarrApiAccess::$user) < 0) {
349 throw new RestException(500, 'Error creating thirdparty', array_merge(array($this->company->error), $this->company->errors));
350 }
351 if (isModEnabled('mailing') && !empty($this->company->email) && isset($this->company->no_email)) {
352 $this->company->setNoEmail($this->company->no_email);
353 }
354
355 return $this->company->id;
356 }
357
375 public function put($id, $request_data = null)
376 {
377 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
378 throw new RestException(403);
379 }
380
381 $result = $this->company->fetch($id);
382 if (!$result) {
383 throw new RestException(404, 'Thirdparty not found');
384 }
385
386 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
387 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
388 }
389
390 foreach ($request_data as $field => $value) {
391 if ($field == 'id') {
392 continue;
393 }
394 if ($field === 'caller') {
395 // 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
396 $this->company->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
397 continue;
398 }
399 if ($field == 'array_options' && is_array($value)) {
400 foreach ($value as $index => $val) {
401 $this->company->array_options[$index] = $this->_checkValExtrafieldsForAPI($index, $val, $this->company);
402 }
403 continue;
404 }
405 $this->company->$field = $this->_checkValForAPI($field, $value, $this->company);
406 }
407
408 if (isModEnabled('mailing') && !empty($this->company->email) && isset($this->company->no_email)) {
409 $this->company->setNoEmail($this->company->no_email);
410 }
411
412 if ($this->company->update($id, DolibarrApiAccess::$user, 1, 1, 1, 'update', 1) > 0) {
413 return $this->get($id);
414 } else {
415 throw new RestException(500, $this->company->error);
416 }
417 }
418
440 public function merge($id, $idtodelete)
441 {
442 if ($id == $idtodelete) {
443 throw new RestException(400, 'Try to merge a thirdparty into itself');
444 }
445
446 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
447 throw new RestException(403);
448 }
449
450 $result = $this->company->fetch($id); // include the fetch of extra fields
451 if (!$result) {
452 throw new RestException(404, 'Thirdparty not found');
453 }
454
455 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
456 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
457 }
458
459 $companytoremove = new Societe($this->db);
460 $result = $companytoremove->fetch($idtodelete); // include the fetch of extra fields
461 if (!$result) {
462 throw new RestException(404, 'Thirdparty not found');
463 }
464
465 if (!DolibarrApi::_checkAccessToResource('societe', $companytoremove->id)) {
466 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
467 }
468
469 $user = DolibarrApiAccess::$user;
470 $result = $this->company->mergeCompany($companytoremove->id);
471 if ($result < 0) {
472 throw new RestException(500, 'Error failed to merged thirdparty '.$companytoremove->id.' into '.$id.'. Enable and read log file for more information.');
473 }
474
475 return $this->get($id);
476 }
477
490 public function delete($id)
491 {
492 if (!DolibarrApiAccess::$user->hasRight('societe', 'supprimer')) {
493 throw new RestException(403);
494 }
495 $result = $this->company->fetch($id);
496 if (!$result) {
497 throw new RestException(404, 'Thirdparty not found');
498 }
499 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
500 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
501 }
502 $this->company->oldcopy = clone $this->company; // @phan-suppress-current-line PhanTypeMismatchProperty
503
504 $res = $this->company->delete($id);
505 if ($res < 0) {
506 throw new RestException(500, "Can't delete, error occurs");
507 } elseif ($res == 0) {
508 throw new RestException(409, "Can't delete, that product is probably used");
509 }
510
511 return array(
512 'success' => array(
513 'code' => 200,
514 'message' => 'Object deleted'
515 )
516 );
517 }
518
536 public function setThirdpartyPriceLevel($id, $priceLevel)
537 {
538 global $conf;
539
540 if (!isModEnabled('societe')) {
541 throw new RestException(501, 'Module "Thirdparties" needed for this request');
542 }
543
544 if (!isModEnabled("product")) {
545 throw new RestException(501, 'Module "Products" needed for this request');
546 }
547
548 if (!getDolGlobalString('PRODUIT_MULTIPRICES') && !getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) {
549 throw new RestException(501, 'Multiprices features activation needed for this request');
550 }
551
552 if ($priceLevel < 1 || $priceLevel > getDolGlobalString('PRODUIT_MULTIPRICES_LIMIT')) {
553 throw new RestException(400, 'Price level must be between 1 and ' . getDolGlobalString('PRODUIT_MULTIPRICES_LIMIT'));
554 }
555
556 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
557 throw new RestException(403, 'Access to thirdparty '.$id.' not allowed for login '.DolibarrApiAccess::$user->login);
558 }
559
560 $result = $this->company->fetch($id);
561 if ($result < 0) {
562 throw new RestException(404, 'Thirdparty '.$id.' not found');
563 }
564
565 if (empty($result)) {
566 throw new RestException(500, 'Error fetching thirdparty '.$id, array_merge(array($this->company->error), $this->company->errors));
567 }
568
569 if (empty(DolibarrApi::_checkAccessToResource('societe', $this->company->id))) {
570 throw new RestException(403, 'Access to thirdparty '.$id.' not allowed for login '.DolibarrApiAccess::$user->login);
571 }
572
573 $result = $this->company->setPriceLevel($priceLevel, DolibarrApiAccess::$user);
574 if ($result <= 0) {
575 throw new RestException(500, 'Error setting new price level for thirdparty '.$id, array($this->company->db->lasterror()));
576 }
577
578 return $this->_cleanObjectDatas($this->company);
579 }
580
594 public function getRepresentative($id)
595 {
596 if (!DolibarrApiAccess::$user->hasRight('societe', 'reader')) {
597 throw new RestException(403);
598 }
599 $result = $this->company->fetch($id);
600 if (!$result) {
601 throw new RestException(404, 'Thirdparty not found');
602 }
603 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
604 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
605 }
606 $result = $this->company->getSalesRepresentatives(DolibarrApiAccess::$user);
609 return $result;
610 }
611
626 public function addRepresentative($id, $representative_id)
627 {
628 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
629 throw new RestException(403);
630 }
631 $result = $this->company->fetch($id);
632 if (!$result) {
633 throw new RestException(404, 'Thirdparty not found');
634 }
635 $usertmp = new User($this->db);
636 $result = $usertmp->fetch($representative_id);
637 if (!$result) {
638 throw new RestException(404, 'User not found');
639 }
640 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
641 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
642 }
643 $result = $this->company->add_commercial(DolibarrApiAccess::$user, $representative_id);
644
645 return $result;
646 }
647
662 public function deleteRepresentative($id, $representative_id)
663 {
664 if (!DolibarrApiAccess::$user->hasRight('societe', 'supprimer')) {
665 throw new RestException(403);
666 }
667 $result = $this->company->fetch($id);
668 if (!$result) {
669 throw new RestException(404, 'Thirdparty not found');
670 }
671 $usertmp = new User($this->db);
672 $result = $usertmp->fetch($representative_id);
673 if (!$result) {
674 throw new RestException(404, 'User not found');
675 }
676 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
677 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
678 }
679 $result = $this->company->del_commercial(DolibarrApiAccess::$user, $representative_id);
680
681 return $result;
682 }
683
702 public function getCategories($id, $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0)
703 {
704 if (!DolibarrApiAccess::$user->hasRight('categorie', 'lire')) {
705 throw new RestException(403);
706 }
707
708 $result = $this->company->fetch($id);
709 if (!$result) {
710 throw new RestException(404, 'Thirdparty not found');
711 }
712
713 // Check that user has permission on thirdparty ID
714 if (!DolibarrApi::_checkAccessToResource('societe', $this->company)) {
715 throw new RestException(404, 'Third party not allowed for login '.DolibarrApiAccess::$user->login);
716 }
717
718 $categories = new Categorie($this->db);
719
720 $arrayofcateg = $categories->getListForItem($id, 'customer', $sortfield, $sortorder, $limit, $page);
721
722 if (is_numeric($arrayofcateg) && $arrayofcateg < 0) {
723 throw new RestException(503, 'Error when retrieve category list : '.$categories->error);
724 }
725
726 if (is_numeric($arrayofcateg) && $arrayofcateg >= 0) { // To fix a return of 0 instead of empty array of method getListForItem
727 return array();
728 }
729
730 return $arrayofcateg;
731 }
732
749 public function addCategory($id, $category_id)
750 {
751 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
752 throw new RestException(403);
753 }
754
755 $result = $this->company->fetch($id);
756 if (!$result) {
757 throw new RestException(404, 'Third party not found');
758 }
759 $category = new Categorie($this->db);
760 $result = $category->fetch($category_id);
761 if (!$result) {
762 throw new RestException(404, 'category not found');
763 }
764
765 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
766 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
767 }
768 if (!DolibarrApi::_checkAccessToResource('category', $category->id)) {
769 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
770 }
771
772 $category->add_type($this->company, 'customer');
773
774 return $this->_cleanObjectDatas($this->company);
775 }
776
793 public function deleteCategory($id, $category_id)
794 {
795 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
796 throw new RestException(403);
797 }
798
799 $result = $this->company->fetch($id);
800 if (!$result) {
801 throw new RestException(404, 'Thirdparty not found');
802 }
803 $category = new Categorie($this->db);
804 $result = $category->fetch($category_id);
805 if (!$result) {
806 throw new RestException(404, 'category not found');
807 }
808
809 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
810 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
811 }
812 if (!DolibarrApi::_checkAccessToResource('category', $category->id)) {
813 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
814 }
815
816 $category->del_type($this->company, 'customer');
817
818 return $this->_cleanObjectDatas($this->company);
819 }
820
840 public function getSupplierCategories($id, $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0)
841 {
842 if (!DolibarrApiAccess::$user->hasRight('categorie', 'lire')) {
843 throw new RestException(403);
844 }
845
846 $result = $this->company->fetch($id);
847 if (!$result) {
848 throw new RestException(404, 'Thirdparty not found');
849 }
850
851 // Check that user has permission on thirdparty ID
852 if (!DolibarrApi::_checkAccessToResource('societe', $this->company)) {
853 throw new RestException(404, 'Third party not allowed for login '.DolibarrApiAccess::$user->login);
854 }
855
856 $categories = new Categorie($this->db);
857
858 $result = $categories->getListForItem($id, 'supplier', $sortfield, $sortorder, $limit, $page);
859
860 if (is_numeric($result) && $result < 0) {
861 throw new RestException(503, 'Error when retrieve category list : '.$categories->error);
862 }
863
864 if (is_numeric($result) && $result == 0) { // To fix a return of 0 instead of empty array of method getListForItem
865 return array();
866 }
867
868 return $result;
869 }
870
887 public function addSupplierCategory($id, $category_id)
888 {
889 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
890 throw new RestException(403);
891 }
892
893 $result = $this->company->fetch($id);
894 if (!$result) {
895 throw new RestException(404, 'Thirdparty not found');
896 }
897 $category = new Categorie($this->db);
898 $result = $category->fetch($category_id);
899 if (!$result) {
900 throw new RestException(404, 'category not found');
901 }
902
903 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
904 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
905 }
906 if (!DolibarrApi::_checkAccessToResource('category', $category->id)) {
907 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
908 }
909
910 $category->add_type($this->company, 'supplier');
911
912 return $this->_cleanObjectDatas($this->company);
913 }
914
931 public function deleteSupplierCategory($id, $category_id)
932 {
933 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
934 throw new RestException(403);
935 }
936
937 $result = $this->company->fetch($id);
938 if (!$result) {
939 throw new RestException(404, 'Thirdparty not found');
940 }
941 $category = new Categorie($this->db);
942 $result = $category->fetch($category_id);
943 if (!$result) {
944 throw new RestException(404, 'category not found');
945 }
946
947 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
948 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
949 }
950 if (!DolibarrApi::_checkAccessToResource('category', $category->id)) {
951 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
952 }
953
954 $category->del_type($this->company, 'supplier');
955
956 return $this->_cleanObjectDatas($this->company);
957 }
958
959
978 public function getOutStandingProposals($id, $mode = 'customer')
979 {
980 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
981 throw new RestException(403);
982 }
983
984 if (empty($id)) {
985 throw new RestException(400, 'Thirdparty ID is mandatory');
986 }
987
988 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
989 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
990 }
991
992 $result = $this->company->fetch($id);
993 if (!$result) {
994 throw new RestException(404, 'Thirdparty not found');
995 }
996
997 $result = $this->company->getOutstandingProposals($mode);
998
999 unset($result['total_ht']);
1000 unset($result['total_ttc']);
1001
1002 return $result;
1003 }
1004
1005
1024 public function getOutStandingOrder($id, $mode = 'customer')
1025 {
1026 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
1027 throw new RestException(403);
1028 }
1029
1030 if (empty($id)) {
1031 throw new RestException(400, 'Thirdparty ID is mandatory');
1032 }
1033
1034 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1035 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1036 }
1037
1038 $result = $this->company->fetch($id);
1039 if (!$result) {
1040 throw new RestException(404, 'Thirdparty not found');
1041 }
1042
1043 $result = $this->company->getOutstandingOrders($mode);
1044
1045 unset($result['total_ht']);
1046 unset($result['total_ttc']);
1047
1048 return $result;
1049 }
1050
1069 public function getOutStandingInvoices($id, $mode = 'customer')
1070 {
1071 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
1072 throw new RestException(403);
1073 }
1074
1075 if (empty($id)) {
1076 throw new RestException(400, 'Thirdparty ID is mandatory');
1077 }
1078
1079 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1080 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1081 }
1082
1083 $result = $this->company->fetch($id);
1084 if (!$result) {
1085 throw new RestException(404, 'Thirdparty not found');
1086 }
1087
1088 $result = $this->company->getOutstandingBills($mode);
1089
1090 unset($result['total_ht']);
1091 unset($result['total_ttc']);
1092
1093 return $result;
1094 }
1095
1114 public function getSalesRepresentatives($id, $mode = 0)
1115 {
1116 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
1117 throw new RestException(403);
1118 }
1119
1120 if (empty($id)) {
1121 throw new RestException(400, 'Thirdparty ID is mandatory');
1122 }
1123
1124 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1125 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1126 }
1127
1128 $result = $this->company->fetch($id);
1129 if ($result <= 0) {
1130 throw new RestException(404, 'Thirdparty not found');
1131 }
1132
1133 $result = $this->company->getSalesRepresentatives(DolibarrApiAccess::$user, $mode);
1134
1135 return $result;
1136 }
1137
1162 public function getFixedAmountDiscounts($id, $mode = 'customer', $filter = "none", $sortfield = "f.type", $sortorder = 'ASC')
1163 {
1164 $obj_ret = array();
1165
1166 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
1167 throw new RestException(403);
1168 }
1169
1170 if (empty($id)) {
1171 throw new RestException(400, 'Thirdparty ID is mandatory');
1172 }
1173
1174 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1175 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1176 }
1177
1178 $result = $this->company->fetch($id);
1179 if (!$result) {
1180 throw new RestException(404, 'Thirdparty not found');
1181 }
1182
1183 $sql = '';
1184 if ($mode === 'customer') {
1185 $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";
1186 $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re";
1187 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON f.rowid = re.fk_facture_source";
1188 $sql .= " WHERE re.fk_soc = ".((int) $id);
1189 if ($filter == "available") {
1190 $sql .= " AND re.fk_facture IS NULL AND re.fk_facture_line IS NULL";
1191 }
1192 if ($filter == "used") {
1193 $sql .= " AND (re.fk_facture IS NOT NULL OR re.fk_facture_line IS NOT NULL)";
1194 }
1195 } elseif ($mode === 'supplier') {
1196 $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";
1197 $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re";
1198 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facture_fourn as f ON f.rowid = re.fk_invoice_supplier_source";
1199 $sql .= " WHERE f.rowid = re.fk_invoice_supplier_source AND re.fk_soc = ".((int) $id);
1200 if ($filter == "available") {
1201 $sql .= " AND re.fk_invoice_supplier IS NULL AND re.fk_invoice_supplier_line IS NULL";
1202 }
1203 if ($filter == "used") {
1204 $sql .= " AND (re.fk_invoice_supplier IS NOT NULL OR re.fk_invoice_supplier_line IS NOT NULL)";
1205 }
1206 }
1207
1208 $sql .= $this->db->order($sortfield, $sortorder);
1209
1210 $result = $this->db->query($sql);
1211 if (!$result) {
1212 throw new RestException(503, $this->db->lasterror());
1213 } else {
1214 //$num = $this->db->num_rows($result);
1215 while ($obj = $this->db->fetch_object($result)) {
1216 $obj_ret[] = $obj;
1217 }
1218 }
1219
1220 return $obj_ret;
1221 }
1222
1247 public function createFixedAmountDiscount($id, $request_data = null)
1248 {
1249 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
1250 throw new RestException(403);
1251 }
1252
1253 // Check mandatory fields
1254 if (empty($id)) {
1255 throw new RestException(400, 'Thirdparty ID is mandatory');
1256 }
1257 if (!isset($request_data['amount'])) {
1258 throw new RestException(400, 'Missing required field: amount');
1259 }
1260 if (!isset($request_data['description'])) {
1261 throw new RestException(400, 'Missing required field: description');
1262 }
1263
1264 // Check access to resource
1265 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1266 throw new RestException(401, 'Access not allowed for login'.DolibarrApiAccess::$user->login);
1267 }
1268
1269 // Fetch thirdparty to verify it exists
1270 if ($this->company->fetch($id) <= 0) {
1271 throw new RestException(404, 'Error creating discount, thirdparty not found');
1272 }
1273
1274
1275 // Validate amount
1276 if (!is_numeric($request_data['amount']) || $request_data['amount'] <= 0) {
1277 throw new RestException(400, 'Invalid amount_ht: must be a positive number');
1278 }
1279 $amount = (float) $request_data['amount'];
1280
1281 // Validate VAT rate
1282 if (isset($request_data['tva_tx']) && (!is_numeric($request_data['tva_tx']) || $request_data['tva_tx'] < 0)) {
1283 throw new RestException(400, 'Invalid tva_tx: must be a positive number or zero');
1284 }
1285 $tva_tx = isset($request_data['tva_tx']) ? (float) $request_data['tva_tx'] : 0;
1286
1287 // Get price base type (HT or TTC) : HT as default
1288 $price_base_type = 'HT';
1289 if (isset($request_data['price_base_type'])) {
1290 $price_base_type = strtoupper($request_data['price_base_type']);
1291 if ($price_base_type !== 'HT' && $price_base_type !== 'TTC') {
1292 throw new RestException(400, 'Invalid price_base_type: must be "HT" or "TTC"');
1293 }
1294 }
1295
1296 // Get discount type (0 = customer, 1 = supplier): 0 as default
1297 $discount_type = 0;
1298 if (isset($request_data['discount_type'])) {
1299 $discount_type = (int) $request_data['discount_type'];
1300 if ($discount_type !== 0 && $discount_type !== 1) {
1301 throw new RestException(400, 'Invalid discount_type: must be 0 (customer) or 1 (supplier)');
1302 }
1303 }
1304
1305 // Get description
1306 $description = $request_data['description'];
1307 if (empty(trim($description))) {
1308 throw new RestException(400, 'Description cannot be empty');
1309 }
1310
1311 // Prepare VAT rate with code if provided
1312 $vatrate = "";
1313 if (isset($request_data['vat_src_code']) && !empty($request_data['vat_src_code'])) {
1314 $vatrate = $tva_tx . ' (' . $request_data['vat_src_code'] . ')';
1315 }
1316
1317 // Create the discount using Societe::set_remise_except()
1318 $this->db->begin();
1319
1320 $result = $this->company->set_remise_except($amount, DolibarrApiAccess::$user, $description, $vatrate, $discount_type, $price_base_type);
1321
1322 if ($result > 0) {
1323 $this->db->commit();
1324 return $result;
1325 } else {
1326 $this->db->rollback();
1327 throw new RestException(500, 'Error creating discount: '.$this->company->error, array_merge(array($this->company->error), $this->company->errors));
1328 }
1329 }
1330
1354 public function splitdiscount($id, $discountid, $amount_ttc_1, $amount_ttc_2)
1355 {
1356 $obj_ret = array();
1357
1358 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer') || !DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
1359 throw new RestException(403);
1360 }
1361
1362 if (empty($id)) {
1363 throw new RestException(400, 'Thirdparty ID is mandatory');
1364 }
1365 if (empty($discountid)) {
1366 throw new RestException(400, 'Discount ID is mandatory');
1367 }
1368 if (empty($amount_ttc_1) || empty($amount_ttc_2)) {
1369 throw new RestException(400, 'Amount are mandatory');
1370 }
1371
1372 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1373 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1374 }
1375
1376 $result = $this->company->fetch($id);
1377 if (!$result) {
1378 throw new RestException(404, 'Thirdparty not found');
1379 }
1380 require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
1381 $discount = new DiscountAbsolute($this->db);
1382 $res = $discount->fetch($discountid);
1383 if (!($res > 0)) {
1384 throw new RestException(404, 'Discount not found');
1385 }
1386 if ($discount->socid != $id) {
1387 throw new RestException(405, 'Discount not owned by this thirdpartie');
1388 }
1389
1390 if (price2num((float) $amount_ttc_1 + (float) $amount_ttc_2) != $discount->amount_ttc) {
1391 throw new RestException(405, 'Sum of the 2 discounts is different that the original discount');
1392 }
1393 if ($discount->fk_facture_line) {
1394 throw new RestException(409, 'Discount is already used');
1395 }
1396
1397 $newdiscount1 = new DiscountAbsolute($this->db);
1398 $newdiscount2 = new DiscountAbsolute($this->db);
1399
1400 $newdiscount1->fk_facture_source = $discount->fk_facture_source;
1401 $newdiscount2->fk_facture_source = $discount->fk_facture_source;
1402 $newdiscount1->fk_facture = $discount->fk_facture;
1403 $newdiscount2->fk_facture = $discount->fk_facture;
1404 $newdiscount1->fk_facture_line = $discount->fk_facture_line;
1405 $newdiscount2->fk_facture_line = $discount->fk_facture_line;
1406 $newdiscount1->fk_invoice_supplier_source = $discount->fk_invoice_supplier_source;
1407 $newdiscount2->fk_invoice_supplier_source = $discount->fk_invoice_supplier_source;
1408 $newdiscount1->fk_invoice_supplier = $discount->fk_invoice_supplier;
1409 $newdiscount2->fk_invoice_supplier = $discount->fk_invoice_supplier;
1410 $newdiscount1->fk_invoice_supplier_line = $discount->fk_invoice_supplier_line;
1411 $newdiscount2->fk_invoice_supplier_line = $discount->fk_invoice_supplier_line;
1412 if ($discount->description == '(CREDIT_NOTE)' || $discount->description == '(DEPOSIT)') {
1413 $newdiscount1->description = $discount->description;
1414 $newdiscount2->description = $discount->description;
1415 } else {
1416 $newdiscount1->description = $discount->description.' (1)';
1417 $newdiscount2->description = $discount->description.' (2)';
1418 }
1419
1420 $newdiscount1->fk_user = $discount->fk_user;
1421 $newdiscount2->fk_user = $discount->fk_user;
1422 $newdiscount1->fk_soc = $discount->fk_soc;
1423 $newdiscount1->socid = $discount->socid;
1424 $newdiscount2->fk_soc = $discount->fk_soc;
1425 $newdiscount2->socid = $discount->socid;
1426 $newdiscount1->discount_type = $discount->discount_type;
1427 $newdiscount2->discount_type = $discount->discount_type;
1428 $newdiscount1->datec = $discount->datec;
1429 $newdiscount2->datec = $discount->datec;
1430 $newdiscount1->tva_tx = $discount->tva_tx;
1431 $newdiscount2->tva_tx = $discount->tva_tx;
1432 $newdiscount1->vat_src_code = $discount->vat_src_code;
1433 $newdiscount2->vat_src_code = $discount->vat_src_code;
1434 $newdiscount1->amount_ttc = $amount_ttc_1;
1435 $newdiscount2->amount_ttc = price2num($discount->amount_ttc - $newdiscount1->amount_ttc);
1436 $newdiscount1->amount_ht = price2num($newdiscount1->amount_ttc / (1 + $newdiscount1->tva_tx / 100), 'MT');
1437 $newdiscount2->amount_ht = price2num($newdiscount2->amount_ttc / (1 + $newdiscount2->tva_tx / 100), 'MT');
1438 $newdiscount1->amount_tva = price2num($newdiscount1->amount_ttc - $newdiscount1->amount_ht);
1439 $newdiscount2->amount_tva = price2num($newdiscount2->amount_ttc - $newdiscount2->amount_ht);
1440
1441 $newdiscount1->multicurrency_amount_ttc = (float) $amount_ttc_1 * ($discount->multicurrency_amount_ttc / $discount->amount_ttc);
1442 $newdiscount2->multicurrency_amount_ttc = price2num($discount->multicurrency_amount_ttc - $newdiscount1->multicurrency_amount_ttc);
1443 $newdiscount1->multicurrency_amount_ht = price2num($newdiscount1->multicurrency_amount_ttc / (1 + $newdiscount1->tva_tx / 100), 'MT');
1444 $newdiscount2->multicurrency_amount_ht = price2num($newdiscount2->multicurrency_amount_ttc / (1 + $newdiscount2->tva_tx / 100), 'MT');
1445 $newdiscount1->multicurrency_amount_tva = price2num($newdiscount1->multicurrency_amount_ttc - $newdiscount1->multicurrency_amount_ht);
1446 $newdiscount2->multicurrency_amount_tva = price2num($newdiscount2->multicurrency_amount_ttc - $newdiscount2->multicurrency_amount_ht);
1447
1448 // 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
1449 // the same for multicurrency_amount_xxx and multicurrency_total_xxx
1450 $newdiscount1->total_ttc = (float) price2num($newdiscount1->amount_ttc);
1451 $newdiscount1->total_ht = (float) price2num($newdiscount1->amount_ht);
1452 $newdiscount1->total_tva = (float) price2num($newdiscount1->amount_tva);
1453 $newdiscount2->total_ttc = (float) price2num($newdiscount2->amount_ttc);
1454 $newdiscount2->total_ht = (float) price2num($newdiscount2->amount_ht);
1455 $newdiscount2->total_tva = (float) price2num($newdiscount2->amount_tva);
1456 $newdiscount1->multicurrency_total_ttc = (float) price2num($newdiscount1->multicurrency_amount_ttc);
1457 $newdiscount1->multicurrency_total_ht = (float) price2num($newdiscount1->multicurrency_amount_ht);
1458 $newdiscount1->multicurrency_total_tva = (float) price2num($newdiscount1->multicurrency_amount_tva);
1459 $newdiscount2->multicurrency_total_ttc = (float) price2num($newdiscount2->multicurrency_amount_ttc);
1460 $newdiscount2->multicurrency_total_ht = (float) price2num($newdiscount2->multicurrency_amount_ht);
1461 $newdiscount2->multicurrency_total_tva = (float) price2num($newdiscount2->multicurrency_amount_tva);
1462
1463 $this->db->begin();
1464
1465 $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
1466 // 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
1467 $discount->fk_invoice_supplier_source = 0;
1468 $res = $discount->delete(DolibarrApiAccess::$user);
1469 $newid1 = $newdiscount1->create(DolibarrApiAccess::$user);
1470 $newid2 = $newdiscount2->create(DolibarrApiAccess::$user);
1471 if ($res <= 0 || $newid1 <= 0 || $newid2 <= 0) {
1472 $this->db->rollback();
1473 throw new RestException(500, 'Operation fail');
1474 }
1475
1476 $this->db->commit();
1477
1478 $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";
1479 $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re, ".MAIN_DB_PREFIX."facture as f";
1480 $sql .= " WHERE re.rowid IN (".((int) $newid1).",".((int) $newid2).") AND f.rowid = re.fk_facture_source AND re.fk_soc = ".((int) $id);
1481
1482 $sql .= $this->db->order("f.type", "ASC");
1483
1484 $result = $this->db->query($sql);
1485 if (!$result) {
1486 throw new RestException(503, $this->db->lasterror());
1487 } else {
1488 // $num = $this->db->num_rows($result);
1489 while ($obj = $this->db->fetch_object($result)) {
1490 $obj_ret[] = $obj;
1491 }
1492 }
1493
1494 return $obj_ret;
1495 }
1496
1497
1516 {
1517 if (!DolibarrApiAccess::$user->hasRight('facture', 'lire')) {
1518 throw new RestException(403);
1519 }
1520 if (empty($id)) {
1521 throw new RestException(400, 'Thirdparty ID is mandatory');
1522 }
1523
1524 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1525 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1526 }
1527
1528 /*$result = $this->thirdparty->fetch($id);
1529 if( ! $result ) {
1530 throw new RestException(404, 'Thirdparty not found');
1531 }*/
1532
1533 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
1534 $invoice = new Facture($this->db);
1535 $result = $invoice->list_replacable_invoices($id);
1536 if ($result < 0) {
1537 throw new RestException(405, $invoice->error);
1538 }
1539
1540 return $result;
1541 }
1542
1565 {
1566 if (!DolibarrApiAccess::$user->hasRight('facture', 'lire')) {
1567 throw new RestException(403);
1568 }
1569 if (empty($id)) {
1570 throw new RestException(400, 'Thirdparty ID is mandatory');
1571 }
1572
1573 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1574 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1575 }
1576
1577 /*$result = $this->thirdparty->fetch($id);
1578 if( ! $result ) {
1579 throw new RestException(404, 'Thirdparty not found');
1580 }*/
1581
1582 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
1583 $invoice = new Facture($this->db);
1584 $result = $invoice->list_qualified_avoir_invoices($id);
1585 if (!is_array($result) && $result < 0) {
1586 throw new RestException(405, $invoice->error);
1587 }
1588
1589 return $result;
1590 }
1591
1608 {
1609 if (empty($id)) {
1610 throw new RestException(400, 'Thirdparty ID is mandatory');
1611 }
1612 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
1613 throw new RestException(403);
1614 }
1615 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1616 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1617 }
1618
1623 $sql = "SELECT rowid as id, fk_action as event, fk_soc as socid, fk_contact as contact_id, type, datec, tms";
1624 $sql .= " FROM ".MAIN_DB_PREFIX."notify_def";
1625 if ($id) {
1626 $sql .= " WHERE fk_soc = ".((int) $id);
1627 }
1628
1629 $result = $this->db->query($sql);
1630 if ($this->db->num_rows($result) == 0) {
1631 throw new RestException(404, 'Notification not found');
1632 }
1633
1634 $i = 0;
1635
1636 $notifications = array();
1637
1638 if ($result) {
1639 $i = 0;
1640 $num = $this->db->num_rows($result);
1641 //$min = min($num, ($limit <= 0 ? $num : $limit));
1642 $min = $num;
1643 while ($i < $min) {
1644 $obj = $this->db->fetch_object($result);
1645 $notifications[] = $obj;
1646 $i++;
1647 }
1648 } else {
1649 throw new RestException(404, 'No notifications found');
1650 }
1651
1652 $fields = array('id', 'socid', 'event', 'contact_id', 'datec', 'tms', 'type');
1653
1654 $returnNotifications = array();
1655
1656 foreach ($notifications as $notification) {
1657 $object = array();
1658 foreach ($notification as $key => $value) {
1659 if (in_array($key, $fields)) {
1660 $object[$key] = $value;
1661 }
1662 }
1663 $returnNotifications[] = $object;
1664 }
1665
1666 // Too complex for phan ?: @phan-suppress-next-line PhanTypeMismatchReturn
1667 return $returnNotifications;
1668 }
1669
1686 public function createCompanyNotification($id, $request_data = null)
1687 {
1688 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
1689 throw new RestException(403, "User has no right to update thirdparties");
1690 }
1691 if ($this->company->fetch($id) <= 0) {
1692 throw new RestException(404, 'Error creating Thirdparty Notification, Thirdparty doesn\'t exists');
1693 }
1694 $notification = new Notify($this->db);
1695
1696 $notification->socid = $id;
1697
1698 foreach ($request_data as $field => $value) {
1699 $notification->$field = $this->_checkValForAPI($field, $value, $notification);
1700 }
1701
1702 $event = $notification->event;
1703 if (!$event) {
1704 throw new RestException(500, 'Error creating Thirdparty Notification, request_data missing event');
1705 }
1706 $socid = $notification->socid;
1707 $contact_id = $notification->contact_id;
1708
1709 $exists_sql = "SELECT rowid, fk_action as event, fk_soc as socid, fk_contact as contact_id, type, datec, tms as datem";
1710 $exists_sql .= " FROM ".MAIN_DB_PREFIX."notify_def";
1711 $exists_sql .= " WHERE fk_action = '".$this->db->escape((string) $event)."'";
1712 $exists_sql .= " AND fk_soc = '".$this->db->escape((string) $socid)."'";
1713 $exists_sql .= " AND fk_contact = '".$this->db->escape((string) $contact_id)."'";
1714
1715 $exists_result = $this->db->query($exists_sql);
1716 if ($this->db->num_rows($exists_result) > 0) {
1717 throw new RestException(403, 'Notification already exists');
1718 }
1719
1720 if ($notification->create(DolibarrApiAccess::$user) < 0) {
1721 throw new RestException(500, 'Error creating Thirdparty Notification');
1722 }
1723
1724 if ($notification->update(DolibarrApiAccess::$user) < 0) {
1725 throw new RestException(500, 'Error updating values');
1726 }
1727
1728 return $this->_cleanObjectDatas($notification);
1729 }
1730
1749 public function createCompanyNotificationByCode($id, $code, $request_data = null)
1750 {
1751 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
1752 throw new RestException(403, "User has no right to update thirdparties");
1753 }
1754 if ($this->company->fetch($id) <= 0) {
1755 throw new RestException(404, 'Error creating Thirdparty Notification, Thirdparty doesn\'t exists');
1756 }
1757 $notification = new Notify($this->db);
1758 $notification->socid = $id;
1759
1760 $sql = "SELECT t.rowid as id FROM ".MAIN_DB_PREFIX."c_action_trigger as t";
1761 $sql .= " WHERE t.code = '".$this->db->escape($code)."'";
1762
1763 $result = $this->db->query($sql);
1764 if ($this->db->num_rows($result) == 0) {
1765 throw new RestException(404, 'Action Trigger code not found');
1766 }
1767
1768 $notification->event = $this->db->fetch_row($result)[0];
1769 foreach ($request_data as $field => $value) {
1770 if ($field === 'event') {
1771 throw new RestException(500, 'Error creating Thirdparty Notification, request_data contains event key');
1772 }
1773 if ($field === 'fk_action') {
1774 throw new RestException(500, 'Error creating Thirdparty Notification, request_data contains fk_action key');
1775 }
1776 $notification->$field = $this->_checkValForAPI($field, $value, $notification);
1777 }
1778
1779 $event = $notification->event;
1780 $socid = $notification->socid;
1781 $contact_id = $notification->contact_id;
1782
1783 $exists_sql = "SELECT rowid, fk_action as event, fk_soc as socid, fk_contact as contact_id, type, datec, tms as datem";
1784 $exists_sql .= " FROM ".MAIN_DB_PREFIX."notify_def";
1785 $exists_sql .= " WHERE fk_action = '".$this->db->escape((string) $event)."'";
1786 $exists_sql .= " AND fk_soc = '".$this->db->escape((string) $socid)."'";
1787 $exists_sql .= " AND fk_contact = '".$this->db->escape((string) $contact_id)."'";
1788
1789 $exists_result = $this->db->query($exists_sql);
1790 if ($this->db->num_rows($exists_result) > 0) {
1791 throw new RestException(403, 'Notification already exists');
1792 }
1793
1794 if ($notification->create(DolibarrApiAccess::$user) < 0) {
1795 throw new RestException(500, 'Error creating Thirdparty Notification, are request_data well formed?');
1796 }
1797
1798 if ($notification->update(DolibarrApiAccess::$user) < 0) {
1799 throw new RestException(500, 'Error updating values');
1800 }
1801
1802 return $this->_cleanObjectDatas($notification);
1803 }
1804
1819 public function deleteCompanyNotification($id, $notification_id)
1820 {
1821 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
1822 throw new RestException(403);
1823 }
1824
1825 $notification = new Notify($this->db);
1826
1827 $notification->fetch($notification_id);
1828
1829 $socid = (int) $notification->socid;
1830
1831 if ($socid == $id) {
1832 return $notification->delete(DolibarrApiAccess::$user);
1833 } else {
1834 throw new RestException(403, "Not allowed due to bad consistency of input data");
1835 }
1836 }
1837
1855 public function updateCompanyNotification($id, $notification_id, $request_data = null)
1856 {
1857 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
1858 throw new RestException(403, "User has no right to update thirdparties");
1859 }
1860 if ($this->company->fetch($id) <= 0) {
1861 throw new RestException(404, 'Error creating Company Notification, Company doesn\'t exists');
1862 }
1863 $notification = new Notify($this->db);
1864
1865 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
1866 $notification->fetch($notification_id, $id);
1867
1868 if ($notification->socid != $id) {
1869 throw new RestException(403, "Not allowed due to bad consistency of input data");
1870 }
1871
1872 foreach ($request_data as $field => $value) {
1873 $notification->$field = $this->_checkValForAPI($field, $value, $notification);
1874 }
1875
1876 if ($notification->update(DolibarrApiAccess::$user) < 0) {
1877 throw new RestException(500, 'Error updating values');
1878 }
1879
1880 return $this->_cleanObjectDatas($notification);
1881 }
1882
1899 {
1900 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
1901 throw new RestException(403);
1902 }
1903 if (empty($id)) {
1904 throw new RestException(400, 'Thirdparty ID is mandatory');
1905 }
1906
1907 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1908 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1909 }
1910
1915 $sql = "SELECT rowid, fk_soc, bank, number, code_banque, code_guichet, cle_rib, bic, iban_prefix as iban, domiciliation as address, proprio,";
1916 $sql .= " owner_address, default_rib, label, datec, tms as datem, rum, frstrecur";
1917 $sql .= " FROM ".MAIN_DB_PREFIX."societe_rib";
1918 if ($id) {
1919 $sql .= " WHERE fk_soc = ".((int) $id);
1920 }
1921
1922 $result = $this->db->query($sql);
1923
1924 if ($this->db->num_rows($result) == 0) {
1925 throw new RestException(404, 'Account not found');
1926 }
1927
1928 $i = 0;
1929
1930 $accounts = array();
1931
1932 if ($result) {
1933 $i = 0;
1934 $num = $this->db->num_rows($result);
1935 //$min = min($num, ($limit <= 0 ? $num : $limit));
1936 $min = $num;
1937 while ($i < $min) {
1938 $obj = $this->db->fetch_object($result);
1939
1940 $account = new CompanyBankAccount($this->db);
1941 if ($account->fetch($obj->rowid)) {
1942 $accounts[] = $account;
1943 }
1944 $i++;
1945 }
1946 } else {
1947 throw new RestException(404, 'Account not found');
1948 }
1949
1950
1951 $fields = array('socid', 'default_rib', 'frstrecur', '1000110000001', 'datec', 'datem', 'label', 'bank', 'bic', 'iban', 'id', 'rum');
1952
1953 $returnAccounts = array();
1954
1955 foreach ($accounts as $account) {
1956 $object = array();
1957 foreach ($account as $key => $value) {
1958 if (in_array($key, $fields)) {
1959 if ($key == 'iban') {
1960 $object[$key] = dolDecrypt($value);
1961 } else {
1962 $object[$key] = $value;
1963 }
1964 }
1965 }
1966 $returnAccounts[] = $object;
1967 }
1968
1969 return $returnAccounts;
1970 }
1971
1988 public function createCompanyBankAccount($id, $request_data = null)
1989 {
1990 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
1991 throw new RestException(403);
1992 }
1993 if ($this->company->fetch($id) <= 0) {
1994 throw new RestException(404, 'Error creating Company Bank account, Company doesn\'t exists');
1995 }
1996
1997 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1998 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1999 }
2000
2001 $account = new CompanyBankAccount($this->db);
2002
2003 $account->socid = $id;
2004
2005 foreach ($request_data as $field => $value) {
2006 if ($field === 'caller') {
2007 // 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
2008 $this->company->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
2009 continue;
2010 }
2011
2012 $account->$field = $this->_checkValForAPI('extrafields', $value, $account);
2013 }
2014
2015 if ($account->create(DolibarrApiAccess::$user) < 0) {
2016 throw new RestException(500, 'Error creating Company Bank account');
2017 }
2018
2019 if (empty($account->rum)) {
2020 require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php';
2021 $prelevement = new BonPrelevement($this->db);
2022 $account->rum = $prelevement->buildRumNumber((string) $this->company->code_client, $account->datec, (string) $account->id);
2023 $account->date_rum = dol_now();
2024 }
2025
2026 if ($account->update(DolibarrApiAccess::$user) < 0) {
2027 throw new RestException(500, 'Error updating values');
2028 }
2029
2030 return $this->_cleanObjectDatas($account);
2031 }
2032
2050 public function updateCompanyBankAccount($id, $bankaccount_id, $request_data = null)
2051 {
2052 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2053 throw new RestException(403);
2054 }
2055 if ($this->company->fetch($id) <= 0) {
2056 throw new RestException(404, 'Error creating Company Bank account, Company doesn\'t exists');
2057 }
2058
2059 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
2060 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
2061 }
2062
2063 $account = new CompanyBankAccount($this->db);
2064
2065 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
2066 $account->fetch($bankaccount_id, '', $id, -1, '');
2067
2068 if ($account->socid != $id) {
2069 throw new RestException(403);
2070 }
2071
2072
2073 foreach ($request_data as $field => $value) {
2074 if ($field === 'caller') {
2075 // 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
2076 $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
2077 continue;
2078 }
2079
2080 $account->$field = $this->_checkValForAPI($field, $value, $account);
2081 }
2082
2083 if (empty($account->rum)) {
2084 require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php';
2085 $prelevement = new BonPrelevement($this->db);
2086 $account->rum = $prelevement->buildRumNumber((string) $this->company->code_client, $account->datec, (string) $account->id);
2087 $account->date_rum = dol_now();
2088 }
2089
2090 if ($account->update(DolibarrApiAccess::$user) < 0) {
2091 throw new RestException(500, 'Error updating values');
2092 }
2093
2094 return $this->_cleanObjectDatas($account);
2095 }
2096
2111 public function deleteCompanyBankAccount($id, $bankaccount_id)
2112 {
2113 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2114 throw new RestException(403);
2115 }
2116
2117 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
2118 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
2119 }
2120
2121 $account = new CompanyBankAccount($this->db);
2122
2123 $account->fetch($bankaccount_id);
2124
2125 $socid = (int) $account->socid;
2126
2127 if ($socid == $id) {
2128 return $account->delete(DolibarrApiAccess::$user);
2129 } else {
2130 throw new RestException(403, "Not allowed due to bad consistency of input data");
2131 }
2132 }
2133
2152 public function generateBankAccountDocument($id, $companybankid = null, $model = 'sepamandate')
2153 {
2154 global $conf, $langs;
2155
2156 $langs->loadLangs(array("main", "dict", "commercial", "products", "companies", "banks", "bills", "withdrawals"));
2157
2158 if ($this->company->fetch($id) <= 0) {
2159 throw new RestException(404, 'Thirdparty not found');
2160 }
2161
2162 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2163 throw new RestException(403);
2164 }
2165
2166 $this->company->setDocModel(DolibarrApiAccess::$user, $model);
2167
2168 $this->company->fk_bank = $this->company->fk_account;
2169 // $this->company->fk_account = $this->company->fk_account;
2170
2171 $outputlangs = $langs;
2172 $newlang = '';
2173
2174 //if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) $newlang = GETPOST('lang_id', 'aZ09');
2175 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
2176 if (isset($this->company->thirdparty->default_lang)) {
2177 $newlang = $this->company->thirdparty->default_lang; // for proposal, order, invoice, ...
2178 } elseif (isset($this->company->default_lang)) {
2179 $newlang = $this->company->default_lang; // for thirdparty
2180 }
2181 }
2182 if (!empty($newlang)) {
2183 $outputlangs = new Translate("", $conf);
2184 $outputlangs->setDefaultLang($newlang);
2185 }
2186
2187 $sql = "SELECT rowid";
2188 $sql .= " FROM ".MAIN_DB_PREFIX."societe_rib";
2189 if ($id) {
2190 $sql .= " WHERE fk_soc = ".((int) $id);
2191 }
2192 if ($companybankid) {
2193 $sql .= " AND rowid = ".((int) $companybankid);
2194 }
2195
2196 $i = 0;
2197 $accounts = array();
2198
2199 $result = $this->db->query($sql);
2200 if ($result) {
2201 if ($this->db->num_rows($result) == 0) {
2202 throw new RestException(404, 'Bank account not found');
2203 }
2204
2205 $num = $this->db->num_rows($result);
2206 //$min = min($num, ($limit <= 0 ? $num : $limit));
2207 $min = $num;
2208 while ($i < $min) {
2209 $obj = $this->db->fetch_object($result);
2210
2211 $account = new CompanyBankAccount($this->db);
2212 if ($account->fetch($obj->rowid)) {
2213 $accounts[] = $account;
2214 }
2215 $i++;
2216 }
2217 } else {
2218 throw new RestException(500, 'Sql error '.$this->db->lasterror());
2219 }
2220
2221 $moreparams = array(
2222 'use_companybankid' => $accounts[0]->id,
2223 'force_dir_output' => $conf->societe->multidir_output[$this->company->entity].'/'.dol_sanitizeFileName((string) $this->company->id)
2224 );
2225
2226 $result = $this->company->generateDocument($model, $outputlangs, 0, 0, 0, $moreparams);
2227
2228 if ($result > 0) {
2229 return array("success" => $result);
2230 } else {
2231 throw new RestException(500, 'Error generating the document '.$this->company->error);
2232 }
2233 }
2234
2252 public function getSocieteAccounts($id, $site = null)
2253 {
2254 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
2255 throw new RestException(403);
2256 }
2257
2258 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
2259 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
2260 }
2261
2265 $sql = "SELECT rowid, fk_soc, key_account, site, date_creation, tms FROM ".MAIN_DB_PREFIX."societe_account";
2266 $sql .= " WHERE fk_soc = ".((int) $id);
2267 if ($site) {
2268 $sql .= " AND site ='".$this->db->escape($site)."'";
2269 }
2270
2271 $result = $this->db->query($sql);
2272
2273 if ($result && $this->db->num_rows($result) == 0) {
2274 throw new RestException(404, 'This thirdparty does not have any account attached or does not exist.');
2275 }
2276
2277 $i = 0;
2278
2279 $accounts = array();
2280
2281 $i = 0;
2282 $num = $this->db->num_rows($result);
2283 //$min = min($num, ($limit <= 0 ? $num : $limit));
2284 $min = $num;
2285 while ($i < $min) {
2286 $obj = $this->db->fetch_object($result);
2287 $account = new SocieteAccount($this->db);
2288
2289 if ($account->fetch($obj->rowid)) {
2290 $accounts[] = $account;
2291 }
2292 $i++;
2293 }
2294
2295 $fields = array('id', 'fk_soc', 'key_account', 'site', 'date_creation', 'tms');
2296
2297 $returnAccounts = array();
2298
2299 foreach ($accounts as $account) {
2300 $object = array();
2301 foreach ($account as $key => $value) {
2302 if (in_array($key, $fields)) {
2303 $object[$key] = $value;
2304 }
2305 }
2306 $returnAccounts[] = $object;
2307 }
2308
2309 return $returnAccounts;
2310 }
2311
2329 public function getSocieteByAccounts($site, $key_account)
2330 {
2331 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
2332 throw new RestException(403);
2333 }
2334
2335 $sql = "SELECT rowid, fk_soc, key_account, site, date_creation, tms FROM ".MAIN_DB_PREFIX."societe_account";
2336 $sql .= " WHERE site = '".$this->db->escape($site)."' AND key_account = '".$this->db->escape($key_account)."'";
2337 $sql .= " AND entity IN (".getEntity('societe').")";
2338
2339 $result = $this->db->query($sql);
2340
2341 if ($result && $this->db->num_rows($result) == 1) {
2342 $obj = $this->db->fetch_object($result);
2343 $returnThirdparty = $this->_fetch($obj->fk_soc);
2344 } else {
2345 throw new RestException(404, 'This account have many thirdparties attached or does not exist.');
2346 }
2347
2348 if (!DolibarrApi::_checkAccessToResource('societe', $returnThirdparty->id)) {
2349 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
2350 }
2351
2352 return $returnThirdparty;
2353 }
2354
2378 public function createSocieteAccount($id, $request_data = null)
2379 {
2380 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2381 throw new RestException(403);
2382 }
2383
2384 if (!isset($request_data['site'])) {
2385 throw new RestException(422, 'Unprocessable Entity: You must pass the site attribute in your request data !');
2386 }
2387
2388 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = ".((int) $id)." AND site = '".$this->db->escape($request_data['site'])."'";
2389 $result = $this->db->query($sql);
2390
2391 if ($result && $this->db->num_rows($result) == 0) {
2392 $account = new SocieteAccount($this->db);
2393 if (!isset($request_data['login'])) {
2394 $account->login = "";
2395 }
2396 $account->fk_soc = $id;
2397
2398 foreach ($request_data as $field => $value) {
2399 if ($field === 'caller') {
2400 // 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
2401 $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
2402 continue;
2403 }
2404
2405 $account->$field = $this->_checkValForAPI($field, $value, $account);
2406 }
2407
2408 if ($account->create(DolibarrApiAccess::$user) < 0) {
2409 throw new RestException(500, 'Error creating SocieteAccount entity. Ensure that the ID of thirdparty provided does exist!');
2410 }
2411
2412 $this->_cleanObjectDatas($account);
2413
2414 return $account;
2415 } else {
2416 throw new RestException(409, 'A SocieteAccount entity already exists for this company and site.');
2417 }
2418 }
2419
2446 public function postSocieteAccount($id, $site, $request_data = null)
2447 {
2448 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2449 throw new RestException(403);
2450 }
2451
2452 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
2453 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
2454 }
2455
2456 $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)."'";
2457 $result = $this->db->query($sql);
2458
2459 // We do not found an existing SocieteAccount entity for this fk_soc and site ; we then create a new one.
2460 if ($result && $this->db->num_rows($result) == 0) {
2461 if (!isset($request_data['key_account'])) {
2462 throw new RestException(422, 'Unprocessable Entity: You must pass the key_account attribute in your request data !');
2463 }
2464 $account = new SocieteAccount($this->db);
2465 if (!isset($request_data['login'])) {
2466 $account->login = "";
2467 }
2468
2469 foreach ($request_data as $field => $value) {
2470 if ($field === 'caller') {
2471 // 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
2472 $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
2473 continue;
2474 }
2475
2476 $account->$field = $this->_checkValForAPI($field, $value, $account);
2477 }
2478
2479 $account->fk_soc = $id;
2480 $account->site = $site;
2481
2482 if ($account->create(DolibarrApiAccess::$user) < 0) {
2483 throw new RestException(500, 'Error creating SocieteAccount entity.');
2484 }
2485 // We found an existing SocieteAccount entity, we are replacing it
2486 } else {
2487 if (isset($request_data['site']) && $request_data['site'] !== $site) {
2488 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = ".((int) $id)." AND site = '".$this->db->escape($request_data['site'])."' ";
2489 $result = $this->db->query($sql);
2490
2491 if ($result && $this->db->num_rows($result) !== 0) {
2492 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.");
2493 }
2494 }
2495
2496 $obj = $this->db->fetch_object($result);
2497
2498 $account = new SocieteAccount($this->db);
2499 $account->id = $obj->rowid;
2500 $account->fk_soc = $id;
2501 $account->site = $site;
2502 if (!isset($request_data['login'])) {
2503 $account->login = "";
2504 }
2505 $account->fk_user_creat = $obj->fk_user_creat;
2506 $account->date_creation = $obj->date_creation;
2507
2508 foreach ($request_data as $field => $value) {
2509 if ($field === 'caller') {
2510 // 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
2511 $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
2512 continue;
2513 }
2514
2515 $account->$field = $this->_checkValForAPI($field, $value, $account);
2516 }
2517
2518 if ($account->update(DolibarrApiAccess::$user) < 0) {
2519 throw new RestException(500, 'Error updating SocieteAccount entity.');
2520 }
2521 }
2522
2523 $this->_cleanObjectDatas($account);
2524
2525 return $account;
2526 }
2527
2548 public function putSocieteAccount($id, $site, $request_data = null)
2549 {
2550 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2551 throw new RestException(403);
2552 }
2553
2554 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
2555 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
2556 }
2557
2558 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = ".((int) $id)." AND site = '".$this->db->escape($site)."'";
2559 $result = $this->db->query($sql);
2560
2561 if ($result && $this->db->num_rows($result) == 0) {
2562 throw new RestException(404, "This thirdparty does not have $site account attached or does not exist.");
2563 } else {
2564 // If the user tries to edit the site member, we check first if
2565 if (isset($request_data['site']) && $request_data['site'] !== $site) {
2566 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = ".((int) $id)." AND site = '".$this->db->escape($request_data['site'])."' ";
2567 $result = $this->db->query($sql);
2568
2569 if ($result && $this->db->num_rows($result) !== 0) {
2570 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.");
2571 }
2572 }
2573
2574 $obj = $this->db->fetch_object($result);
2575 $account = new SocieteAccount($this->db);
2576 $account->fetch($obj->rowid);
2577
2578 foreach ($request_data as $field => $value) {
2579 if ($field === 'caller') {
2580 // 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
2581 $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
2582 continue;
2583 }
2584
2585 $account->$field = $this->_checkValForAPI($field, $value, $account);
2586 }
2587
2588 if ($account->update(DolibarrApiAccess::$user) < 0) {
2589 throw new RestException(500, 'Error updating SocieteAccount account');
2590 }
2591
2592 $this->_cleanObjectDatas($account);
2593
2594 return $account;
2595 }
2596 }
2597
2616 public function deleteSocieteAccount($id, $site)
2617 {
2618 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2619 throw new RestException(403);
2620 }
2621
2622 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
2623 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
2624 }
2625
2626 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = ".((int) $id)." AND site = '".$this->db->escape($site)."'";
2627 $result = $this->db->query($sql);
2628
2629 if ($result && $this->db->num_rows($result) == 0) {
2630 throw new RestException(404);
2631 } else {
2632 $obj = $this->db->fetch_object($result);
2633 $account = new SocieteAccount($this->db);
2634 $account->fetch($obj->rowid);
2635
2636 if ($account->delete(DolibarrApiAccess::$user) < 0) {
2637 throw new RestException(500, "Error while deleting $site account attached to this third party");
2638 }
2639 }
2640 }
2641
2658 {
2659 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2660 throw new RestException(403);
2661 }
2662
2667 $sql = "SELECT rowid, fk_soc, key_account, site, date_creation, tms";
2668 $sql .= " FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = ".((int) $id);
2669
2670 $result = $this->db->query($sql);
2671
2672 if ($result && $this->db->num_rows($result) == 0) {
2673 throw new RestException(404, 'This third party does not have any account attached or does not exist.');
2674 } else {
2675 $i = 0;
2676
2677 $i = 0;
2678 $num = $this->db->num_rows($result);
2679 //$min = min($num, ($limit <= 0 ? $num : $limit));
2680 $min = $num;
2681 while ($i < $min) {
2682 $obj = $this->db->fetch_object($result);
2683 $account = new SocieteAccount($this->db);
2684 $account->fetch($obj->rowid);
2685
2686 if ($account->delete(DolibarrApiAccess::$user) < 0) {
2687 throw new RestException(500, 'Error while deleting account attached to this third party');
2688 }
2689 $i++;
2690 }
2691 }
2692 }
2693
2694 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2704 protected function _cleanObjectDatas($object)
2705 {
2706 // phpcs:enable
2707 $object = parent::_cleanObjectDatas($object);
2708
2709 unset($object->nom); // ->name already defined and nom deprecated
2710 unset($object->name_bis); // ->name_alias already defined
2711 unset($object->note); // ->note_private and note_public already defined
2712 unset($object->departement);
2713 unset($object->departement_code);
2714 unset($object->pays);
2715 unset($object->particulier);
2716 unset($object->prefix_comm);
2717
2718 unset($object->siren);
2719 unset($object->siret);
2720 unset($object->ape);
2721
2722 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.
2723
2724 unset($object->total_ht);
2725 unset($object->total_tva);
2726 unset($object->total_localtax1);
2727 unset($object->total_localtax2);
2728 unset($object->total_ttc);
2729
2730 unset($object->lines);
2731 unset($object->thirdparty);
2732
2733 unset($object->fk_delivery_address); // deprecated feature
2734
2735 return $object;
2736 }
2737
2746 private function _validate($data)
2747 {
2748 if ($data === null) {
2749 $data = array();
2750 }
2751 $thirdparty = array();
2752 foreach (Thirdparties::$FIELDS as $field) {
2753 if (!isset($data[$field])) {
2754 throw new RestException(400, "$field field missing");
2755 }
2756 $thirdparty[$field] = $data[$field];
2757 }
2758 return $thirdparty;
2759 }
2760
2784 private function _fetch($rowid, $ref = '', $ref_ext = '', $barcode = '', $idprof1 = '', $idprof2 = '', $idprof3 = '', $idprof4 = '', $idprof5 = '', $idprof6 = '', $email = '', $ref_alias = '')
2785 {
2786 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
2787 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login.'. No read permission on thirdparties.');
2788 }
2789
2790 if ($rowid === 0) {
2791 $result = $this->company->initAsSpecimen();
2792 } else {
2793 $result = $this->company->fetch((int) $rowid, $ref, $ref_ext, $barcode, $idprof1, $idprof2, $idprof3, $idprof4, $idprof5, $idprof6, $email, $ref_alias);
2794 }
2795 if (!$result) {
2796 throw new RestException(404, 'Thirdparty not found');
2797 }
2798
2799 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
2800 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login.' on this thirdparty');
2801 }
2802 if (isModEnabled('mailing')) {
2803 $this->company->getNoEmail();
2804 }
2805
2806 if (getDolGlobalString('FACTURE_DEPOSITS_ARE_JUST_PAYMENTS')) {
2807 $filterabsolutediscount = "fk_facture_source IS NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
2808 $filtercreditnote = "fk_facture_source IS NOT NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
2809 } else {
2810 $filterabsolutediscount = "fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')";
2811 $filtercreditnote = "fk_facture_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%')";
2812 }
2813
2814 $absolute_discount = $this->company->getAvailableDiscounts(null, $filterabsolutediscount);
2815 $absolute_creditnote = $this->company->getAvailableDiscounts(null, $filtercreditnote);
2816 $this->company->absolute_discount = price2num($absolute_discount, 'MT');
2817 $this->company->absolute_creditnote = price2num($absolute_creditnote, 'MT');
2818
2819 return $this->_cleanObjectDatas($this->company);
2820 }
2821}
$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.
_checkValForAPI($field, $value, $object)
Check and convert a string depending on its type/name.
static _checkAccessToResource($resource, $resource_id=0, $dbtablename='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $parenttableforentity='')
Check access by user to a given resource.
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.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
forgeSQLFromUniversalSearchCriteria($filter, &$errorstr='', $noand=0, $nopar=0, $noerror=0, $forbiddenfields=array())
forgeSQLFromUniversalSearchCriteria
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
dolDecrypt($chain, $key='', $patterntotest='')
Decode a string with a symmetric encryption.