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-2026 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->lasterror());
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->errorsToString());
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->errorsToString());
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->errorsToString());
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->errorsToString());
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->errorsToString());
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
1692 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1693 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1694 }
1695
1696 if ($this->company->fetch($id) <= 0) {
1697 throw new RestException(404, 'Error creating Thirdparty Notification, Thirdparty doesn\'t exists');
1698 }
1699 $notification = new Notify($this->db);
1700
1701 $notification->socid = $id;
1702
1703 foreach ($request_data as $field => $value) {
1704 $notification->$field = $this->_checkValForAPI($field, $value, $notification);
1705 }
1706
1707 $event = $notification->event;
1708 if (!$event) {
1709 throw new RestException(500, 'Error creating Thirdparty Notification, request_data missing event');
1710 }
1711 $socid = $notification->socid;
1712 $contact_id = $notification->contact_id;
1713
1714 $exists_sql = "SELECT rowid, fk_action as event, fk_soc as socid, fk_contact as contact_id, type, datec, tms as datem";
1715 $exists_sql .= " FROM ".MAIN_DB_PREFIX."notify_def";
1716 $exists_sql .= " WHERE fk_action = '".$this->db->escape((string) $event)."'";
1717 $exists_sql .= " AND fk_soc = '".$this->db->escape((string) $socid)."'";
1718 $exists_sql .= " AND fk_contact = '".$this->db->escape((string) $contact_id)."'";
1719
1720 $exists_result = $this->db->query($exists_sql);
1721 if ($this->db->num_rows($exists_result) > 0) {
1722 throw new RestException(403, 'Notification already exists');
1723 }
1724
1725 if ($notification->create(DolibarrApiAccess::$user) < 0) {
1726 throw new RestException(500, 'Error creating Thirdparty Notification');
1727 }
1728
1729 if ($notification->update(DolibarrApiAccess::$user) < 0) {
1730 throw new RestException(500, 'Error updating values');
1731 }
1732
1733 return $this->_cleanObjectDatas($notification);
1734 }
1735
1754 public function createCompanyNotificationByCode($id, $code, $request_data = null)
1755 {
1756 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
1757 throw new RestException(403, "User has no right to update thirdparties");
1758 }
1759
1760 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1761 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1762 }
1763
1764 if ($this->company->fetch($id) <= 0) {
1765 throw new RestException(404, 'Error creating Thirdparty Notification, Thirdparty doesn\'t exists');
1766 }
1767 $notification = new Notify($this->db);
1768 $notification->socid = $id;
1769
1770 $sql = "SELECT t.rowid as id FROM ".MAIN_DB_PREFIX."c_action_trigger as t";
1771 $sql .= " WHERE t.code = '".$this->db->escape($code)."'";
1772
1773 $result = $this->db->query($sql);
1774 if ($this->db->num_rows($result) == 0) {
1775 throw new RestException(404, 'Action Trigger code not found');
1776 }
1777
1778 $notification->event = $this->db->fetch_row($result)[0];
1779 foreach ($request_data as $field => $value) {
1780 if ($field === 'event') {
1781 throw new RestException(500, 'Error creating Thirdparty Notification, request_data contains event key');
1782 }
1783 if ($field === 'fk_action') {
1784 throw new RestException(500, 'Error creating Thirdparty Notification, request_data contains fk_action key');
1785 }
1786 $notification->$field = $this->_checkValForAPI($field, $value, $notification);
1787 }
1788
1789 $event = $notification->event;
1790 $socid = $notification->socid;
1791 $contact_id = $notification->contact_id;
1792
1793 $exists_sql = "SELECT rowid, fk_action as event, fk_soc as socid, fk_contact as contact_id, type, datec, tms as datem";
1794 $exists_sql .= " FROM ".MAIN_DB_PREFIX."notify_def";
1795 $exists_sql .= " WHERE fk_action = '".$this->db->escape((string) $event)."'";
1796 $exists_sql .= " AND fk_soc = '".$this->db->escape((string) $socid)."'";
1797 $exists_sql .= " AND fk_contact = '".$this->db->escape((string) $contact_id)."'";
1798
1799 $exists_result = $this->db->query($exists_sql);
1800 if ($this->db->num_rows($exists_result) > 0) {
1801 throw new RestException(403, 'Notification already exists');
1802 }
1803
1804 if ($notification->create(DolibarrApiAccess::$user) < 0) {
1805 throw new RestException(500, 'Error creating Thirdparty Notification, are request_data well formed?');
1806 }
1807
1808 if ($notification->update(DolibarrApiAccess::$user) < 0) {
1809 throw new RestException(500, 'Error updating values');
1810 }
1811
1812 return $this->_cleanObjectDatas($notification);
1813 }
1814
1829 public function deleteCompanyNotification($id, $notification_id)
1830 {
1831 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
1832 throw new RestException(403);
1833 }
1834
1835 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1836 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1837 }
1838
1839 $notification = new Notify($this->db);
1840
1841 $notification->fetch($notification_id);
1842
1843 $socid = (int) $notification->socid;
1844
1845 if ($socid == $id) {
1846 return $notification->delete(DolibarrApiAccess::$user);
1847 } else {
1848 throw new RestException(403, "Not allowed due to bad consistency of input data");
1849 }
1850 }
1851
1869 public function updateCompanyNotification($id, $notification_id, $request_data = null)
1870 {
1871 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
1872 throw new RestException(403, "User has no right to update thirdparties");
1873 }
1874
1875 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1876 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1877 }
1878
1879 if ($this->company->fetch($id) <= 0) {
1880 throw new RestException(404, 'Error creating Company Notification, Company doesn\'t exists');
1881 }
1882 $notification = new Notify($this->db);
1883
1884 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
1885 $notification->fetch($notification_id, $id);
1886
1887 if ($notification->socid != $id) {
1888 throw new RestException(403, "Not allowed due to bad consistency of input data");
1889 }
1890
1891 foreach ($request_data as $field => $value) {
1892 $notification->$field = $this->_checkValForAPI($field, $value, $notification);
1893 }
1894
1895 if ($notification->update(DolibarrApiAccess::$user) < 0) {
1896 throw new RestException(500, 'Error updating values');
1897 }
1898
1899 return $this->_cleanObjectDatas($notification);
1900 }
1901
1918 {
1919 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
1920 throw new RestException(403);
1921 }
1922 if (empty($id)) {
1923 throw new RestException(400, 'Thirdparty ID is mandatory');
1924 }
1925
1926 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1927 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1928 }
1929
1934 $sql = "SELECT rowid, fk_soc, bank, number, code_banque, code_guichet, cle_rib, bic, iban_prefix as iban, domiciliation as address, proprio,";
1935 $sql .= " owner_address, default_rib, label, datec, tms as datem, rum, frstrecur";
1936 $sql .= " FROM ".MAIN_DB_PREFIX."societe_rib";
1937 if ($id) {
1938 $sql .= " WHERE fk_soc = ".((int) $id);
1939 }
1940
1941 $result = $this->db->query($sql);
1942
1943 if ($this->db->num_rows($result) == 0) {
1944 throw new RestException(404, 'Account not found');
1945 }
1946
1947 $i = 0;
1948
1949 $accounts = array();
1950
1951 if ($result) {
1952 $i = 0;
1953 $num = $this->db->num_rows($result);
1954 //$min = min($num, ($limit <= 0 ? $num : $limit));
1955 $min = $num;
1956 while ($i < $min) {
1957 $obj = $this->db->fetch_object($result);
1958
1959 $account = new CompanyBankAccount($this->db);
1960 if ($account->fetch($obj->rowid)) {
1961 $accounts[] = $account;
1962 }
1963 $i++;
1964 }
1965 } else {
1966 throw new RestException(404, 'Account not found');
1967 }
1968
1969
1970 $fields = array('socid', 'default_rib', 'frstrecur', '1000110000001', 'datec', 'datem', 'label', 'bank', 'bic', 'iban', 'id', 'rum');
1971
1972 $returnAccounts = array();
1973
1974 foreach ($accounts as $account) {
1975 $object = array();
1976 foreach ($account as $key => $value) {
1977 if (in_array($key, $fields)) {
1978 if ($key == 'iban') {
1979 $object[$key] = dolDecrypt($value);
1980 } else {
1981 $object[$key] = $value;
1982 }
1983 }
1984 }
1985 $returnAccounts[] = $object;
1986 }
1987
1988 return $returnAccounts;
1989 }
1990
2007 public function createCompanyBankAccount($id, $request_data = null)
2008 {
2009 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2010 throw new RestException(403);
2011 }
2012 if ($this->company->fetch($id) <= 0) {
2013 throw new RestException(404, 'Error creating Company Bank account, Company doesn\'t exists');
2014 }
2015
2016 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
2017 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
2018 }
2019
2020 $account = new CompanyBankAccount($this->db);
2021
2022 $account->socid = $id;
2023
2024 foreach ($request_data as $field => $value) {
2025 if ($field === 'caller') {
2026 // 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
2027 $this->company->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
2028 continue;
2029 }
2030
2031 $account->$field = $this->_checkValForAPI('extrafields', $value, $account);
2032 }
2033
2034 if ($account->create(DolibarrApiAccess::$user) < 0) {
2035 throw new RestException(500, 'Error creating Company Bank account');
2036 }
2037
2038 if (empty($account->rum)) {
2039 require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php';
2040 $prelevement = new BonPrelevement($this->db);
2041 $account->rum = $prelevement->buildRumNumber((string) $this->company->code_client, $account->datec, (string) $account->id);
2042 $account->date_rum = dol_now();
2043 }
2044
2045 if ($account->update(DolibarrApiAccess::$user) < 0) {
2046 throw new RestException(500, 'Error updating values');
2047 }
2048
2049 return $this->_cleanObjectDatas($account);
2050 }
2051
2069 public function updateCompanyBankAccount($id, $bankaccount_id, $request_data = null)
2070 {
2071 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2072 throw new RestException(403);
2073 }
2074 if ($this->company->fetch($id) <= 0) {
2075 throw new RestException(404, 'Error creating Company Bank account, Company doesn\'t exists');
2076 }
2077
2078 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
2079 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
2080 }
2081
2082 $account = new CompanyBankAccount($this->db);
2083
2084 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
2085 $account->fetch($bankaccount_id, '', $id, -1, '');
2086
2087 if ($account->socid != $id) {
2088 throw new RestException(403);
2089 }
2090
2091
2092 foreach ($request_data as $field => $value) {
2093 if ($field === 'caller') {
2094 // 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
2095 $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
2096 continue;
2097 }
2098
2099 $account->$field = $this->_checkValForAPI($field, $value, $account);
2100 }
2101
2102 if (empty($account->rum)) {
2103 require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php';
2104 $prelevement = new BonPrelevement($this->db);
2105 $account->rum = $prelevement->buildRumNumber((string) $this->company->code_client, $account->datec, (string) $account->id);
2106 $account->date_rum = dol_now();
2107 }
2108
2109 if ($account->update(DolibarrApiAccess::$user) < 0) {
2110 throw new RestException(500, 'Error updating values');
2111 }
2112
2113 return $this->_cleanObjectDatas($account);
2114 }
2115
2130 public function deleteCompanyBankAccount($id, $bankaccount_id)
2131 {
2132 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2133 throw new RestException(403);
2134 }
2135
2136 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
2137 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
2138 }
2139
2140 $account = new CompanyBankAccount($this->db);
2141
2142 $account->fetch($bankaccount_id);
2143
2144 $socid = (int) $account->socid;
2145
2146 if ($socid == $id) {
2147 return $account->delete(DolibarrApiAccess::$user);
2148 } else {
2149 throw new RestException(403, "Not allowed due to bad consistency of input data");
2150 }
2151 }
2152
2171 public function generateBankAccountDocument($id, $companybankid = null, $model = 'sepamandate')
2172 {
2173 global $conf, $langs;
2174
2175 $langs->loadLangs(array("main", "dict", "commercial", "products", "companies", "banks", "bills", "withdrawals"));
2176
2177 if ($this->company->fetch($id) <= 0) {
2178 throw new RestException(404, 'Thirdparty not found');
2179 }
2180
2181 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2182 throw new RestException(403);
2183 }
2184
2185 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
2186 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
2187 }
2188
2189 $this->company->setDocModel(DolibarrApiAccess::$user, $model);
2190
2191 $this->company->fk_bank = $this->company->fk_account;
2192 // $this->company->fk_account = $this->company->fk_account;
2193
2194 $outputlangs = $langs;
2195 $newlang = '';
2196
2197 //if (getDolGlobalInt('MAIN_MULTILANGS') && GETPOST('lang_id', 'aZ09')) $newlang = GETPOST('lang_id', 'aZ09');
2198 if (getDolGlobalInt('MAIN_MULTILANGS')) {
2199 if (isset($this->company->thirdparty->default_lang)) {
2200 $newlang = $this->company->thirdparty->default_lang; // for proposal, order, invoice, ...
2201 } elseif (isset($this->company->default_lang)) {
2202 $newlang = $this->company->default_lang; // for thirdparty
2203 }
2204 }
2205 if (!empty($newlang)) {
2206 $outputlangs = new Translate("", $conf);
2207 $outputlangs->setDefaultLang($newlang);
2208 }
2209
2210 $sql = "SELECT rowid";
2211 $sql .= " FROM ".MAIN_DB_PREFIX."societe_rib";
2212 if ($id) {
2213 $sql .= " WHERE fk_soc = ".((int) $id);
2214 }
2215 if ($companybankid) {
2216 $sql .= " AND rowid = ".((int) $companybankid);
2217 }
2218
2219 $i = 0;
2220 $accounts = array();
2221
2222 $result = $this->db->query($sql);
2223 if ($result) {
2224 if ($this->db->num_rows($result) == 0) {
2225 throw new RestException(404, 'Bank account not found');
2226 }
2227
2228 $num = $this->db->num_rows($result);
2229 //$min = min($num, ($limit <= 0 ? $num : $limit));
2230 $min = $num;
2231 while ($i < $min) {
2232 $obj = $this->db->fetch_object($result);
2233
2234 $account = new CompanyBankAccount($this->db);
2235 if ($account->fetch($obj->rowid)) {
2236 $accounts[] = $account;
2237 }
2238 $i++;
2239 }
2240 } else {
2241 throw new RestException(500, 'Sql error '.$this->db->lasterror());
2242 }
2243
2244 $moreparams = array(
2245 'use_companybankid' => $accounts[0]->id,
2246 'force_dir_output' => $conf->societe->multidir_output[$this->company->entity].'/'.dol_sanitizeFileName((string) $this->company->id)
2247 );
2248
2249 $result = $this->company->generateDocument($model, $outputlangs, 0, 0, 0, $moreparams);
2250
2251 if ($result > 0) {
2252 return array("success" => $result);
2253 } else {
2254 throw new RestException(500, 'Error generating the document '.$this->company->errorsToString());
2255 }
2256 }
2257
2275 public function getSocieteAccounts($id, $site = null)
2276 {
2277 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
2278 throw new RestException(403);
2279 }
2280
2281 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
2282 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
2283 }
2284
2288 $sql = "SELECT rowid, fk_soc, key_account, site, date_creation, tms FROM ".MAIN_DB_PREFIX."societe_account";
2289 $sql .= " WHERE fk_soc = ".((int) $id);
2290 if ($site) {
2291 $sql .= " AND site ='".$this->db->escape($site)."'";
2292 }
2293
2294 $result = $this->db->query($sql);
2295
2296 if ($result && $this->db->num_rows($result) == 0) {
2297 throw new RestException(404, 'This thirdparty does not have any account attached or does not exist.');
2298 }
2299
2300 $i = 0;
2301
2302 $accounts = array();
2303
2304 $i = 0;
2305 $num = $this->db->num_rows($result);
2306 //$min = min($num, ($limit <= 0 ? $num : $limit));
2307 $min = $num;
2308 while ($i < $min) {
2309 $obj = $this->db->fetch_object($result);
2310 $account = new SocieteAccount($this->db);
2311
2312 if ($account->fetch($obj->rowid)) {
2313 $accounts[] = $account;
2314 }
2315 $i++;
2316 }
2317
2318 $fields = array('id', 'fk_soc', 'key_account', 'site', 'date_creation', 'tms');
2319
2320 $returnAccounts = array();
2321
2322 foreach ($accounts as $account) {
2323 $object = array();
2324 foreach ($account as $key => $value) {
2325 if (in_array($key, $fields)) {
2326 $object[$key] = $value;
2327 }
2328 }
2329 $returnAccounts[] = $object;
2330 }
2331
2332 return $returnAccounts;
2333 }
2334
2352 public function getSocieteByAccounts($site, $key_account)
2353 {
2354 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
2355 throw new RestException(403);
2356 }
2357
2358 $sql = "SELECT rowid, fk_soc, key_account, site, date_creation, tms FROM ".MAIN_DB_PREFIX."societe_account";
2359 $sql .= " WHERE site = '".$this->db->escape($site)."' AND key_account = '".$this->db->escape($key_account)."'";
2360 $sql .= " AND entity IN (".getEntity('societe').")";
2361
2362 $result = $this->db->query($sql);
2363
2364 if ($result && $this->db->num_rows($result) == 1) {
2365 $obj = $this->db->fetch_object($result);
2366 $returnThirdparty = $this->_fetch($obj->fk_soc);
2367 } else {
2368 throw new RestException(404, 'This account have many thirdparties attached or does not exist.');
2369 }
2370
2371 if (!DolibarrApi::_checkAccessToResource('societe', $returnThirdparty->id)) {
2372 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
2373 }
2374
2375 return $returnThirdparty;
2376 }
2377
2401 public function createSocieteAccount($id, $request_data = null)
2402 {
2403 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2404 throw new RestException(403);
2405 }
2406
2407 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
2408 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
2409 }
2410
2411 if (!isset($request_data['site'])) {
2412 throw new RestException(422, 'Unprocessable Entity: You must pass the site attribute in your request data !');
2413 }
2414
2415 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = ".((int) $id)." AND site = '".$this->db->escape($request_data['site'])."'";
2416 $result = $this->db->query($sql);
2417
2418 if ($result && $this->db->num_rows($result) == 0) {
2419 $account = new SocieteAccount($this->db);
2420 if (!isset($request_data['login'])) {
2421 $account->login = "";
2422 }
2423 $account->fk_soc = $id;
2424
2425 foreach ($request_data as $field => $value) {
2426 if ($field === 'caller') {
2427 // 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
2428 $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
2429 continue;
2430 }
2431
2432 $account->$field = $this->_checkValForAPI($field, $value, $account);
2433 }
2434
2435 if ($account->create(DolibarrApiAccess::$user) < 0) {
2436 throw new RestException(500, 'Error creating SocieteAccount entity. Ensure that the ID of thirdparty provided does exist!');
2437 }
2438
2439 $this->_cleanObjectDatas($account);
2440
2441 return $account;
2442 } else {
2443 throw new RestException(409, 'A SocieteAccount entity already exists for this company and site.');
2444 }
2445 }
2446
2473 public function postSocieteAccount($id, $site, $request_data = null)
2474 {
2475 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2476 throw new RestException(403);
2477 }
2478
2479 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
2480 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
2481 }
2482
2483 $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)."'";
2484 $result = $this->db->query($sql);
2485
2486 // We do not found an existing SocieteAccount entity for this fk_soc and site ; we then create a new one.
2487 if ($result && $this->db->num_rows($result) == 0) {
2488 if (!isset($request_data['key_account'])) {
2489 throw new RestException(422, 'Unprocessable Entity: You must pass the key_account attribute in your request data !');
2490 }
2491 $account = new SocieteAccount($this->db);
2492 if (!isset($request_data['login'])) {
2493 $account->login = "";
2494 }
2495
2496 foreach ($request_data as $field => $value) {
2497 if ($field === 'caller') {
2498 // 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
2499 $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
2500 continue;
2501 }
2502
2503 $account->$field = $this->_checkValForAPI($field, $value, $account);
2504 }
2505
2506 $account->fk_soc = $id;
2507 $account->site = $site;
2508
2509 if ($account->create(DolibarrApiAccess::$user) < 0) {
2510 throw new RestException(500, 'Error creating SocieteAccount entity.');
2511 }
2512 // We found an existing SocieteAccount entity, we are replacing it
2513 } else {
2514 if (isset($request_data['site']) && $request_data['site'] !== $site) {
2515 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = ".((int) $id)." AND site = '".$this->db->escape($request_data['site'])."' ";
2516 $result = $this->db->query($sql);
2517
2518 if ($result && $this->db->num_rows($result) !== 0) {
2519 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.");
2520 }
2521 }
2522
2523 $obj = $this->db->fetch_object($result);
2524
2525 $account = new SocieteAccount($this->db);
2526 $account->id = $obj->rowid;
2527 $account->fk_soc = $id;
2528 $account->site = $site;
2529 if (!isset($request_data['login'])) {
2530 $account->login = "";
2531 }
2532 $account->fk_user_creat = $obj->fk_user_creat;
2533 $account->date_creation = $obj->date_creation;
2534
2535 foreach ($request_data as $field => $value) {
2536 if ($field === 'caller') {
2537 // 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
2538 $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
2539 continue;
2540 }
2541
2542 $account->$field = $this->_checkValForAPI($field, $value, $account);
2543 }
2544
2545 if ($account->update(DolibarrApiAccess::$user) < 0) {
2546 throw new RestException(500, 'Error updating SocieteAccount entity.');
2547 }
2548 }
2549
2550 $this->_cleanObjectDatas($account);
2551
2552 return $account;
2553 }
2554
2575 public function putSocieteAccount($id, $site, $request_data = null)
2576 {
2577 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2578 throw new RestException(403);
2579 }
2580
2581 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
2582 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
2583 }
2584
2585 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = ".((int) $id)." AND site = '".$this->db->escape($site)."'";
2586 $result = $this->db->query($sql);
2587
2588 if ($result && $this->db->num_rows($result) == 0) {
2589 throw new RestException(404, "This thirdparty does not have $site account attached or does not exist.");
2590 } else {
2591 // If the user tries to edit the site member, we check first if
2592 if (isset($request_data['site']) && $request_data['site'] !== $site) {
2593 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = ".((int) $id)." AND site = '".$this->db->escape($request_data['site'])."' ";
2594 $result = $this->db->query($sql);
2595
2596 if ($result && $this->db->num_rows($result) !== 0) {
2597 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.");
2598 }
2599 }
2600
2601 $obj = $this->db->fetch_object($result);
2602 $account = new SocieteAccount($this->db);
2603 $account->fetch($obj->rowid);
2604
2605 foreach ($request_data as $field => $value) {
2606 if ($field === 'caller') {
2607 // 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
2608 $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
2609 continue;
2610 }
2611
2612 $account->$field = $this->_checkValForAPI($field, $value, $account);
2613 }
2614
2615 if ($account->update(DolibarrApiAccess::$user) < 0) {
2616 throw new RestException(500, 'Error updating SocieteAccount account');
2617 }
2618
2619 $this->_cleanObjectDatas($account);
2620
2621 return $account;
2622 }
2623 }
2624
2643 public function deleteSocieteAccount($id, $site)
2644 {
2645 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2646 throw new RestException(403);
2647 }
2648
2649 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
2650 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
2651 }
2652
2653 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = ".((int) $id)." AND site = '".$this->db->escape($site)."'";
2654 $result = $this->db->query($sql);
2655
2656 if ($result && $this->db->num_rows($result) == 0) {
2657 throw new RestException(404);
2658 } else {
2659 $obj = $this->db->fetch_object($result);
2660 $account = new SocieteAccount($this->db);
2661 $account->fetch($obj->rowid);
2662
2663 if ($account->delete(DolibarrApiAccess::$user) < 0) {
2664 throw new RestException(500, "Error while deleting $site account attached to this third party");
2665 }
2666 }
2667 }
2668
2685 {
2686 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2687 throw new RestException(403);
2688 }
2689
2690 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
2691 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
2692 }
2693
2698 $sql = "SELECT rowid, fk_soc, key_account, site, date_creation, tms";
2699 $sql .= " FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = ".((int) $id);
2700
2701 $result = $this->db->query($sql);
2702
2703 if ($result && $this->db->num_rows($result) == 0) {
2704 throw new RestException(404, 'This third party does not have any account attached or does not exist.');
2705 } else {
2706 $i = 0;
2707
2708 $i = 0;
2709 $num = $this->db->num_rows($result);
2710 //$min = min($num, ($limit <= 0 ? $num : $limit));
2711 $min = $num;
2712 while ($i < $min) {
2713 $obj = $this->db->fetch_object($result);
2714 $account = new SocieteAccount($this->db);
2715 $account->fetch($obj->rowid);
2716
2717 if ($account->delete(DolibarrApiAccess::$user) < 0) {
2718 throw new RestException(500, 'Error while deleting account attached to this third party');
2719 }
2720 $i++;
2721 }
2722 }
2723 }
2724
2725 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2735 protected function _cleanObjectDatas($object)
2736 {
2737 // phpcs:enable
2738 $object = parent::_cleanObjectDatas($object);
2739
2740 unset($object->nom); // ->name already defined and nom deprecated
2741 unset($object->name_bis); // ->name_alias already defined
2742 unset($object->note); // ->note_private and note_public already defined
2743 unset($object->departement);
2744 unset($object->departement_code);
2745 unset($object->pays);
2746 unset($object->particulier);
2747 unset($object->prefix_comm);
2748
2749 unset($object->siren);
2750 unset($object->siret);
2751 unset($object->ape);
2752
2753 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.
2754
2755 unset($object->total_ht);
2756 unset($object->total_tva);
2757 unset($object->total_localtax1);
2758 unset($object->total_localtax2);
2759 unset($object->total_ttc);
2760
2761 unset($object->lines);
2762 unset($object->thirdparty);
2763
2764 unset($object->fk_delivery_address); // deprecated feature
2765
2766 return $object;
2767 }
2768
2777 private function _validate($data)
2778 {
2779 if ($data === null) {
2780 $data = array();
2781 }
2782 $thirdparty = array();
2783 foreach (Thirdparties::$FIELDS as $field) {
2784 if (!isset($data[$field])) {
2785 throw new RestException(400, "$field field missing");
2786 }
2787 $thirdparty[$field] = $data[$field];
2788 }
2789 return $thirdparty;
2790 }
2791
2815 private function _fetch($rowid, $ref = '', $ref_ext = '', $barcode = '', $idprof1 = '', $idprof2 = '', $idprof3 = '', $idprof4 = '', $idprof5 = '', $idprof6 = '', $email = '', $ref_alias = '')
2816 {
2817 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
2818 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login.'. No read permission on thirdparties.');
2819 }
2820
2821 if ($rowid === 0) {
2822 $result = $this->company->initAsSpecimen();
2823 } else {
2824 $result = $this->company->fetch((int) $rowid, $ref, $ref_ext, $barcode, $idprof1, $idprof2, $idprof3, $idprof4, $idprof5, $idprof6, $email, $ref_alias);
2825 }
2826 if (!$result) {
2827 throw new RestException(404, 'Thirdparty not found');
2828 }
2829
2830 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
2831 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login.' on this thirdparty');
2832 }
2833 if (isModEnabled('mailing')) {
2834 $this->company->getNoEmail();
2835 }
2836
2837 if (getDolGlobalString('FACTURE_DEPOSITS_ARE_JUST_PAYMENTS')) {
2838 $filterabsolutediscount = "fk_facture_source IS NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
2839 $filtercreditnote = "fk_facture_source IS NOT NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
2840 } else {
2841 $filterabsolutediscount = "fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')";
2842 $filtercreditnote = "fk_facture_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%')";
2843 }
2844
2845 $absolute_discount = $this->company->getAvailableDiscounts(null, $filterabsolutediscount);
2846 $absolute_creditnote = $this->company->getAvailableDiscounts(null, $filtercreditnote);
2847 $this->company->absolute_discount = price2num($absolute_discount, 'MT');
2848 $this->company->absolute_creditnote = price2num($absolute_creditnote, 'MT');
2849
2850 return $this->_cleanObjectDatas($this->company);
2851 }
2852}
$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:
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.
dolDecrypt($chain, $key='', $patterntotest='')
Decode a string with a symmetric encryption.