dolibarr 24.0.0-beta
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-2025 MDW <mdeweerd@users.noreply.github.com>
8 * Copyright (C) 2024 Jon Bendtsen <jon.bendtsen.github@jonb.dk>
9 * Copyright (C) 2025 William Mead <william@m34d.com>
10 * Copyright (C) 2025 Charlene Benke <charlene@patas-monkey.com>
11 * Copyright (C) 2026 Benjamin Falière <benjamin@faliere.com>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <https://www.gnu.org/licenses/>.
25 */
26
27use Luracast\Restler\RestException;
28
38{
42 public static $FIELDS = array(
43 'name'
44 );
45
49 public $company;
50
54 public function __construct()
55 {
56 global $db;
57 $this->db = $db;
58
59 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
60 require_once DOL_DOCUMENT_ROOT.'/societe/class/societeaccount.class.php';
61 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
62 require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php';
63 require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
64
65 $this->company = new Societe($this->db);
66
67 if (getDolGlobalString('SOCIETE_EMAIL_MANDATORY')) {
68 static::$FIELDS[] = 'email';
69 }
70 }
71
84 public function get($id)
85 {
86 return $this->_fetch($id);
87 }
88
105 public function getByEmail($email)
106 {
107 return $this->_fetch(null, '', '', '', '', '', '', '', '', '', $email);
108 }
109
124 public function getByBarcode($barcode)
125 {
126 return $this->_fetch(null, '', '', $barcode);
127 }
128
155 public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $mode = 0, $category = 0, $sqlfilters = '', $properties = '', $pagination_data = false)
156 {
157 $obj_ret = array();
158
159 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
160 throw new RestException(403);
161 }
162
163 // case of external user, we force socids
164 $socids = DolibarrApiAccess::$user->socid ? (string) DolibarrApiAccess::$user->socid : '';
165
166 // If the internal user must only see his customers, force searching by him
167 $search_sale = 0;
168 if (!DolibarrApiAccess::$user->hasRight('societe', 'client', 'voir') && !$socids) {
169 $search_sale = DolibarrApiAccess::$user->id;
170 }
171
172 $sql = "SELECT t.rowid";
173 $sql .= " FROM ".MAIN_DB_PREFIX."societe as t";
174 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_extrafields AS ef ON ef.fk_object = t.rowid"; // So we will be able to filter on extrafields
175 if ($category > 0) {
176 if ($mode != 4) {
177 $sql .= ", ".MAIN_DB_PREFIX."categorie_societe as c";
178 }
179 if (!in_array($mode, array(1, 2, 3))) {
180 $sql .= ", ".MAIN_DB_PREFIX."categorie_fournisseur as cc";
181 }
182 }
183 $sql .= " WHERE t.entity IN (".getEntity('societe').")";
184 if ($mode == 1) {
185 $sql .= " AND t.client IN (1, 3)";
186 } elseif ($mode == 2) {
187 $sql .= " AND t.client IN (2, 3)";
188 } elseif ($mode == 3) {
189 $sql .= " AND t.client IN (0)";
190 } elseif ($mode == 4) {
191 $sql .= " AND t.fournisseur IN (1)";
192 }
193 // Select third parties of a given category
194 if ($category > 0) {
195 if (!empty($mode) && $mode != 4) {
196 $sql .= " AND c.fk_categorie = ".((int) $category)." AND c.fk_soc = t.rowid";
197 } elseif (!empty($mode) && $mode == 4) {
198 $sql .= " AND cc.fk_categorie = ".((int) $category)." AND cc.fk_soc = t.rowid";
199 } else {
200 $sql .= " AND ((c.fk_categorie = ".((int) $category)." AND c.fk_soc = t.rowid) OR (cc.fk_categorie = ".((int) $category)." AND cc.fk_soc = t.rowid))";
201 }
202 }
203 if ($socids) {
204 $sql .= " AND t.rowid IN (".$this->db->sanitize($socids).")";
205 }
206 // Search on sale representative
207 if ($search_sale && $search_sale != '-1') {
208 if ($search_sale == -2) {
209 $sql .= " AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = t.rowid)";
210 } elseif ($search_sale > 0) {
211 $sql .= " AND EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = t.rowid AND sc.fk_user = ".((int) $search_sale).")";
212 }
213 }
214 // Add sql filters
215 if ($sqlfilters) {
216 $errormessage = '';
217 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
218 if ($errormessage) {
219 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
220 }
221 }
222
223 //this query will return total thirdparties with the filters given
224 $sqlTotals = str_replace('SELECT t.rowid', 'SELECT count(t.rowid) as total', $sql);
225
226 $sql .= $this->db->order($sortfield, $sortorder);
227 if ($limit) {
228 if ($page < 0) {
229 $page = 0;
230 }
231 $offset = $limit * $page;
232
233 $sql .= $this->db->plimit($limit + 1, $offset);
234 }
235
236 $result = $this->db->query($sql);
237 if ($result) {
238 $num = $this->db->num_rows($result);
239 $min = min($num, ($limit <= 0 ? $num : $limit));
240 $i = 0;
241 while ($i < $min) {
242 $obj = $this->db->fetch_object($result);
243 $soc_static = new Societe($this->db);
244 if ($soc_static->fetch($obj->rowid)) {
245 if (isModEnabled('mailing')) {
246 $soc_static->getNoEmail();
247 }
248 $obj_ret[] = $this->_filterObjectProperties($this->_cleanObjectDatas($soc_static), $properties);
249 }
250 $i++;
251 }
252 } else {
253 throw new RestException(503, 'Error when retrieve third parties : '.$this->db->lasterror());
254 }
255 if (!count($obj_ret)) {
256 $message = '';
257 switch ($mode) {
258 case 0:
259 $message = 'No third parties found';
260 break;
261 case 1:
262 $message = 'No customers found';
263 break;
264 case 2:
265 $message = 'No prospects found';
266 break;
267 case 3:
268 $message = 'No other third parties found';
269 break;
270 case 4:
271 $message = 'No suppliers found';
272 }
273 throw new RestException(404, $message);
274 }
275
276 //if $pagination_data is true, the response will contain element data with all values and element pagination with pagination data(total,page,limit)
277 if ($pagination_data) {
278 $totalsResult = $this->db->query($sqlTotals);
279 $total = $this->db->fetch_object($totalsResult)->total;
280
281 $tmp = $obj_ret;
282 $obj_ret = [];
283
284 $obj_ret['data'] = $tmp;
285 $obj_ret['pagination'] = [
286 'total' => (int) $total,
287 'page' => $page, //count starts from 0
288 'page_count' => ceil((int) $total / $limit),
289 'limit' => $limit
290 ];
291 }
292
293 return $obj_ret;
294 }
295
308 public function post($request_data = null)
309 {
310 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
311 throw new RestException(403);
312 }
313
314 // External api user does not know internal country ID
315 if (!isset($request_data['country_id']) && isset($request_data['country_code'])) {
316 $field = strlen($request_data['country_code']) > 2 ? 'code_iso' : 'code';
317 $id = dol_getIdFromCode($this->db, $request_data['country_code'], "c_country", $field, "rowid");
318 if ($id < 0) {
319 throw new RestException(404, 'Country code not found in database: ' . $this->db->error);
320 }
321 $request_data['country_id'] = $id;
322 }
323
324 // Check mandatory fields
325 $result = $this->_validate($request_data);
326
327 foreach ($request_data as $field => $value) {
328 if ($field === 'caller') {
329 // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
330 $this->company->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
331 continue;
332 }
333 if ($field == 'array_options' && is_array($value)) {
334 $this->company->fetch_optionals(); // To force the load of the extrafields definition by fetch_name_optionals_label()
335
336 foreach ($value as $index => $val) {
337 $this->company->array_options[$index] = $this->_checkValExtrafieldsForAPI($index, $val, $this->company);
338 }
339 continue;
340 }
341
342 $this->company->$field = $this->_checkValForAPI($field, $value, $this->company);
343 }
344
345 if ($this->company->create(DolibarrApiAccess::$user) < 0) {
346 throw new RestException(500, 'Error creating thirdparty', array_merge(array($this->company->error), $this->company->errors));
347 }
348 if (isModEnabled('mailing') && !empty($this->company->email) && isset($this->company->no_email)) {
349 $this->company->setNoEmail($this->company->no_email);
350 }
351
352 return $this->company->id;
353 }
354
372 public function put($id, $request_data = null)
373 {
374 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
375 throw new RestException(403);
376 }
377
378 $result = $this->company->fetch($id);
379 if (!$result) {
380 throw new RestException(404, 'Thirdparty not found');
381 }
382
383 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
384 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
385 }
386
387 foreach ($request_data as $field => $value) {
388 if ($field == 'id') {
389 continue;
390 }
391 if ($field === 'caller') {
392 // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
393 $this->company->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
394 continue;
395 }
396 if ($field == 'array_options' && is_array($value)) {
397 foreach ($value as $index => $val) {
398 $this->company->array_options[$index] = $this->_checkValExtrafieldsForAPI($index, $val, $this->company);
399 }
400 continue;
401 }
402 $this->company->$field = $this->_checkValForAPI($field, $value, $this->company);
403 }
404
405 if (isModEnabled('mailing') && !empty($this->company->email) && isset($this->company->no_email)) {
406 $this->company->setNoEmail($this->company->no_email);
407 }
408
409 if ($this->company->update($id, DolibarrApiAccess::$user, 1, 1, 1, 'update', 1) > 0) {
410 return $this->get($id);
411 } else {
412 throw new RestException(500, $this->company->error);
413 }
414 }
415
437 public function merge($id, $idtodelete)
438 {
439 if ($id == $idtodelete) {
440 throw new RestException(400, 'Try to merge a thirdparty into itself');
441 }
442
443 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
444 throw new RestException(403);
445 }
446
447 $result = $this->company->fetch($id); // include the fetch of extra fields
448 if (!$result) {
449 throw new RestException(404, 'Thirdparty not found');
450 }
451
452 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
453 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
454 }
455
456 $companytoremove = new Societe($this->db);
457 $result = $companytoremove->fetch($idtodelete); // include the fetch of extra fields
458 if (!$result) {
459 throw new RestException(404, 'Thirdparty not found');
460 }
461
462 if (!DolibarrApi::_checkAccessToResource('societe', $companytoremove->id)) {
463 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
464 }
465
466 $user = DolibarrApiAccess::$user;
467 $result = $this->company->mergeCompany($companytoremove->id);
468 if ($result < 0) {
469 throw new RestException(500, 'Error failed to merged thirdparty '.$companytoremove->id.' into '.$id.'. Enable and read log file for more information.');
470 }
471
472 return $this->get($id);
473 }
474
487 public function delete($id)
488 {
489 if (!DolibarrApiAccess::$user->hasRight('societe', 'supprimer')) {
490 throw new RestException(403);
491 }
492 $result = $this->company->fetch($id);
493 if (!$result) {
494 throw new RestException(404, 'Thirdparty not found');
495 }
496 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
497 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
498 }
499 $this->company->oldcopy = clone $this->company; // @phan-suppress-current-line PhanTypeMismatchProperty
500
501 $res = $this->company->delete($id);
502 if ($res < 0) {
503 throw new RestException(500, "Can't delete, error occurs");
504 } elseif ($res == 0) {
505 throw new RestException(409, "Can't delete, that product is probably used");
506 }
507
508 return array(
509 'success' => array(
510 'code' => 200,
511 'message' => 'Object deleted'
512 )
513 );
514 }
515
533 public function setThirdpartyPriceLevel($id, $priceLevel)
534 {
535 global $conf;
536
537 if (!isModEnabled('societe')) {
538 throw new RestException(501, 'Module "Thirdparties" needed for this request');
539 }
540
541 if (!isModEnabled("product")) {
542 throw new RestException(501, 'Module "Products" needed for this request');
543 }
544
545 if (!getDolGlobalString('PRODUIT_MULTIPRICES') && !getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) {
546 throw new RestException(501, 'Multiprices features activation needed for this request');
547 }
548
549 if ($priceLevel < 1 || $priceLevel > getDolGlobalString('PRODUIT_MULTIPRICES_LIMIT')) {
550 throw new RestException(400, 'Price level must be between 1 and ' . getDolGlobalString('PRODUIT_MULTIPRICES_LIMIT'));
551 }
552
553 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
554 throw new RestException(403, 'Access to thirdparty '.$id.' not allowed for login '.DolibarrApiAccess::$user->login);
555 }
556
557 $result = $this->company->fetch($id);
558 if ($result < 0) {
559 throw new RestException(404, 'Thirdparty '.$id.' not found');
560 }
561
562 if (empty($result)) {
563 throw new RestException(500, 'Error fetching thirdparty '.$id, array_merge(array($this->company->error), $this->company->errors));
564 }
565
566 if (empty(DolibarrApi::_checkAccessToResource('societe', $this->company->id))) {
567 throw new RestException(403, 'Access to thirdparty '.$id.' not allowed for login '.DolibarrApiAccess::$user->login);
568 }
569
570 $result = $this->company->setPriceLevel($priceLevel, DolibarrApiAccess::$user);
571 if ($result <= 0) {
572 throw new RestException(500, 'Error setting new price level for thirdparty '.$id, array($this->company->db->lasterror()));
573 }
574
575 return $this->_cleanObjectDatas($this->company);
576 }
577
592 public function addRepresentative($id, $representative_id)
593 {
594 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
595 throw new RestException(403);
596 }
597 $result = $this->company->fetch($id);
598 if (!$result) {
599 throw new RestException(404, 'Thirdparty not found');
600 }
601 $usertmp = new User($this->db);
602 $result = $usertmp->fetch($representative_id);
603 if (!$result) {
604 throw new RestException(404, 'User not found');
605 }
606 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
607 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
608 }
609 $result = $this->company->add_commercial(DolibarrApiAccess::$user, $representative_id);
610
611 return $result;
612 }
613
628 public function deleteRepresentative($id, $representative_id)
629 {
630 if (!DolibarrApiAccess::$user->hasRight('societe', 'supprimer')) {
631 throw new RestException(403);
632 }
633 $result = $this->company->fetch($id);
634 if (!$result) {
635 throw new RestException(404, 'Thirdparty not found');
636 }
637 $usertmp = new User($this->db);
638 $result = $usertmp->fetch($representative_id);
639 if (!$result) {
640 throw new RestException(404, 'User not found');
641 }
642 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
643 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
644 }
645 $result = $this->company->del_commercial(DolibarrApiAccess::$user, $representative_id);
646
647 return $result;
648 }
649
668 public function getCategories($id, $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0)
669 {
670 if (!DolibarrApiAccess::$user->hasRight('categorie', 'lire')) {
671 throw new RestException(403);
672 }
673
674 $result = $this->company->fetch($id);
675 if (!$result) {
676 throw new RestException(404, 'Thirdparty not found');
677 }
678
679 $categories = new Categorie($this->db);
680
681 $arrayofcateg = $categories->getListForItem($id, 'customer', $sortfield, $sortorder, $limit, $page);
682
683 if (is_numeric($arrayofcateg) && $arrayofcateg < 0) {
684 throw new RestException(503, 'Error when retrieve category list : '.$categories->error);
685 }
686
687 if (is_numeric($arrayofcateg) && $arrayofcateg >= 0) { // To fix a return of 0 instead of empty array of method getListForItem
688 return array();
689 }
690
691 return $arrayofcateg;
692 }
693
710 public function addCategory($id, $category_id)
711 {
712 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
713 throw new RestException(403);
714 }
715
716 $result = $this->company->fetch($id);
717 if (!$result) {
718 throw new RestException(404, 'Thirdparty not found');
719 }
720 $category = new Categorie($this->db);
721 $result = $category->fetch($category_id);
722 if (!$result) {
723 throw new RestException(404, 'category not found');
724 }
725
726 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
727 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
728 }
729 if (!DolibarrApi::_checkAccessToResource('category', $category->id)) {
730 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
731 }
732
733 $category->add_type($this->company, 'customer');
734
735 return $this->_cleanObjectDatas($this->company);
736 }
737
754 public function deleteCategory($id, $category_id)
755 {
756 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
757 throw new RestException(403);
758 }
759
760 $result = $this->company->fetch($id);
761 if (!$result) {
762 throw new RestException(404, 'Thirdparty not found');
763 }
764 $category = new Categorie($this->db);
765 $result = $category->fetch($category_id);
766 if (!$result) {
767 throw new RestException(404, 'category not found');
768 }
769
770 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
771 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
772 }
773 if (!DolibarrApi::_checkAccessToResource('category', $category->id)) {
774 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
775 }
776
777 $category->del_type($this->company, 'customer');
778
779 return $this->_cleanObjectDatas($this->company);
780 }
781
801 public function getSupplierCategories($id, $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0)
802 {
803 if (!DolibarrApiAccess::$user->hasRight('categorie', 'lire')) {
804 throw new RestException(403);
805 }
806
807 $result = $this->company->fetch($id);
808 if (!$result) {
809 throw new RestException(404, 'Thirdparty not found');
810 }
811
812 $categories = new Categorie($this->db);
813
814 $result = $categories->getListForItem($id, 'supplier', $sortfield, $sortorder, $limit, $page);
815
816 if (is_numeric($result) && $result < 0) {
817 throw new RestException(503, 'Error when retrieve category list : '.$categories->error);
818 }
819
820 if (is_numeric($result) && $result == 0) { // To fix a return of 0 instead of empty array of method getListForItem
821 return array();
822 }
823
824 return $result;
825 }
826
843 public function addSupplierCategory($id, $category_id)
844 {
845 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
846 throw new RestException(403);
847 }
848
849 $result = $this->company->fetch($id);
850 if (!$result) {
851 throw new RestException(404, 'Thirdparty not found');
852 }
853 $category = new Categorie($this->db);
854 $result = $category->fetch($category_id);
855 if (!$result) {
856 throw new RestException(404, 'category not found');
857 }
858
859 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
860 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
861 }
862 if (!DolibarrApi::_checkAccessToResource('category', $category->id)) {
863 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
864 }
865
866 $category->add_type($this->company, 'supplier');
867
868 return $this->_cleanObjectDatas($this->company);
869 }
870
887 public function deleteSupplierCategory($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->del_type($this->company, 'supplier');
911
912 return $this->_cleanObjectDatas($this->company);
913 }
914
915
934 public function getOutStandingProposals($id, $mode = 'customer')
935 {
936 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
937 throw new RestException(403);
938 }
939
940 if (empty($id)) {
941 throw new RestException(400, 'Thirdparty ID is mandatory');
942 }
943
944 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
945 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
946 }
947
948 $result = $this->company->fetch($id);
949 if (!$result) {
950 throw new RestException(404, 'Thirdparty not found');
951 }
952
953 $result = $this->company->getOutstandingProposals($mode);
954
955 unset($result['total_ht']);
956 unset($result['total_ttc']);
957
958 return $result;
959 }
960
961
980 public function getOutStandingOrder($id, $mode = 'customer')
981 {
982 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
983 throw new RestException(403);
984 }
985
986 if (empty($id)) {
987 throw new RestException(400, 'Thirdparty ID is mandatory');
988 }
989
990 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
991 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
992 }
993
994 $result = $this->company->fetch($id);
995 if (!$result) {
996 throw new RestException(404, 'Thirdparty not found');
997 }
998
999 $result = $this->company->getOutstandingOrders($mode);
1000
1001 unset($result['total_ht']);
1002 unset($result['total_ttc']);
1003
1004 return $result;
1005 }
1006
1025 public function getOutStandingInvoices($id, $mode = 'customer')
1026 {
1027 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
1028 throw new RestException(403);
1029 }
1030
1031 if (empty($id)) {
1032 throw new RestException(400, 'Thirdparty ID is mandatory');
1033 }
1034
1035 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1036 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1037 }
1038
1039 $result = $this->company->fetch($id);
1040 if (!$result) {
1041 throw new RestException(404, 'Thirdparty not found');
1042 }
1043
1044 $result = $this->company->getOutstandingBills($mode);
1045
1046 unset($result['total_ht']);
1047 unset($result['total_ttc']);
1048
1049 return $result;
1050 }
1051
1070 public function getSalesRepresentatives($id, $mode = 0)
1071 {
1072 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
1073 throw new RestException(403);
1074 }
1075
1076 if (empty($id)) {
1077 throw new RestException(400, 'Thirdparty ID is mandatory');
1078 }
1079
1080 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1081 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1082 }
1083
1084 $result = $this->company->fetch($id);
1085 if ($result <= 0) {
1086 throw new RestException(404, 'Thirdparty not found');
1087 }
1088
1089 $result = $this->company->getSalesRepresentatives(DolibarrApiAccess::$user, $mode);
1090
1091 return $result;
1092 }
1093
1118 public function getFixedAmountDiscounts($id, $mode = 'customer', $filter = "none", $sortfield = "f.type", $sortorder = 'ASC')
1119 {
1120 $obj_ret = array();
1121
1122 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
1123 throw new RestException(403);
1124 }
1125
1126 if (empty($id)) {
1127 throw new RestException(400, 'Thirdparty ID is mandatory');
1128 }
1129
1130 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1131 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1132 }
1133
1134 $result = $this->company->fetch($id);
1135 if (!$result) {
1136 throw new RestException(404, 'Thirdparty not found');
1137 }
1138
1139 $sql = '';
1140 if ($mode === 'customer') {
1141 $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";
1142 $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re";
1143 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON f.rowid = re.fk_facture_source";
1144 $sql .= " WHERE re.fk_soc = ".((int) $id);
1145 if ($filter == "available") {
1146 $sql .= " AND re.fk_facture IS NULL AND re.fk_facture_line IS NULL";
1147 }
1148 if ($filter == "used") {
1149 $sql .= " AND (re.fk_facture IS NOT NULL OR re.fk_facture_line IS NOT NULL)";
1150 }
1151 } elseif ($mode === 'supplier') {
1152 $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";
1153 $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re";
1154 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facture_fourn as f ON f.rowid = re.fk_invoice_supplier_source";
1155 $sql .= " WHERE f.rowid = re.fk_invoice_supplier_source AND re.fk_soc = ".((int) $id);
1156 if ($filter == "available") {
1157 $sql .= " AND re.fk_invoice_supplier IS NULL AND re.fk_invoice_supplier_line IS NULL";
1158 }
1159 if ($filter == "used") {
1160 $sql .= " AND (re.fk_invoice_supplier IS NOT NULL OR re.fk_invoice_supplier_line IS NOT NULL)";
1161 }
1162 }
1163
1164 $sql .= $this->db->order($sortfield, $sortorder);
1165
1166 $result = $this->db->query($sql);
1167 if (!$result) {
1168 throw new RestException(503, $this->db->lasterror());
1169 } else {
1170 //$num = $this->db->num_rows($result);
1171 while ($obj = $this->db->fetch_object($result)) {
1172 $obj_ret[] = $obj;
1173 }
1174 }
1175
1176 return $obj_ret;
1177 }
1178
1203 public function createFixedAmountDiscount($id, $request_data = null)
1204 {
1205 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
1206 throw new RestException(403);
1207 }
1208
1209 // Check mandatory fields
1210 if (empty($id)) {
1211 throw new RestException(400, 'Thirdparty ID is mandatory');
1212 }
1213 if (!isset($request_data['amount'])) {
1214 throw new RestException(400, 'Missing required field: amount');
1215 }
1216 if (!isset($request_data['description'])) {
1217 throw new RestException(400, 'Missing required field: description');
1218 }
1219
1220 // Check access to resource
1221 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1222 throw new RestException(401, 'Access not allowed for login'.DolibarrApiAccess::$user->login);
1223 }
1224
1225 // Fetch thirdparty to verify it exists
1226 if ($this->company->fetch($id) <= 0) {
1227 throw new RestException(404, 'Error creating discount, thirdparty not found');
1228 }
1229
1230
1231 // Validate amount
1232 if (!is_numeric($request_data['amount']) || $request_data['amount'] <= 0) {
1233 throw new RestException(400, 'Invalid amount_ht: must be a positive number');
1234 }
1235 $amount = (float) $request_data['amount'];
1236
1237 // Validate VAT rate
1238 if (isset($request_data['tva_tx']) && (!is_numeric($request_data['tva_tx']) || $request_data['tva_tx'] < 0)) {
1239 throw new RestException(400, 'Invalid tva_tx: must be a positive number or zero');
1240 }
1241 $tva_tx = isset($request_data['tva_tx']) ? (float) $request_data['tva_tx'] : 0;
1242
1243 // Get price base type (HT or TTC) : HT as default
1244 $price_base_type = 'HT';
1245 if (isset($request_data['price_base_type'])) {
1246 $price_base_type = strtoupper($request_data['price_base_type']);
1247 if ($price_base_type !== 'HT' && $price_base_type !== 'TTC') {
1248 throw new RestException(400, 'Invalid price_base_type: must be "HT" or "TTC"');
1249 }
1250 }
1251
1252 // Get discount type (0 = customer, 1 = supplier): 0 as default
1253 $discount_type = 0;
1254 if (isset($request_data['discount_type'])) {
1255 $discount_type = (int) $request_data['discount_type'];
1256 if ($discount_type !== 0 && $discount_type !== 1) {
1257 throw new RestException(400, 'Invalid discount_type: must be 0 (customer) or 1 (supplier)');
1258 }
1259 }
1260
1261 // Get description
1262 $description = $request_data['description'];
1263 if (empty(trim($description))) {
1264 throw new RestException(400, 'Description cannot be empty');
1265 }
1266
1267 // Prepare VAT rate with code if provided
1268 $vatrate = "";
1269 if (isset($request_data['vat_src_code']) && !empty($request_data['vat_src_code'])) {
1270 $vatrate = $tva_tx . ' (' . $request_data['vat_src_code'] . ')';
1271 }
1272
1273 // Create the discount using Societe::set_remise_except()
1274 $this->db->begin();
1275
1276 $result = $this->company->set_remise_except($amount, DolibarrApiAccess::$user, $description, $vatrate, $discount_type, $price_base_type);
1277
1278 if ($result > 0) {
1279 $this->db->commit();
1280 return $result;
1281 } else {
1282 $this->db->rollback();
1283 throw new RestException(500, 'Error creating discount: '.$this->company->error, array_merge(array($this->company->error), $this->company->errors));
1284 }
1285 }
1286
1310 public function splitdiscount($id, $discountid, $amount_ttc_1, $amount_ttc_2)
1311 {
1312 $obj_ret = array();
1313
1314 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer') || !DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
1315 throw new RestException(403);
1316 }
1317
1318 if (empty($id)) {
1319 throw new RestException(400, 'Thirdparty ID is mandatory');
1320 }
1321 if (empty($discountid)) {
1322 throw new RestException(400, 'Discount ID is mandatory');
1323 }
1324 if (empty($amount_ttc_1) || empty($amount_ttc_2)) {
1325 throw new RestException(400, 'Amount are mandatory');
1326 }
1327
1328 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1329 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1330 }
1331
1332 $result = $this->company->fetch($id);
1333 if (!$result) {
1334 throw new RestException(404, 'Thirdparty not found');
1335 }
1336 require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
1337 $discount = new DiscountAbsolute($this->db);
1338 $res = $discount->fetch($discountid);
1339 if (!($res > 0)) {
1340 throw new RestException(404, 'Discount not found');
1341 }
1342 if ($discount->socid != $id) {
1343 throw new RestException(405, 'Discount not owned by this thirdpartie');
1344 }
1345
1346 if ( price2num((float) $amount_ttc_1 + (float) $amount_ttc_2) != $discount->amount_ttc) {
1347 throw new RestException(405, 'Sum of the 2 discounts is different that the original discount');
1348 }
1349 if ($discount->fk_facture_line) {
1350 throw new RestException(409, 'Discount is already used');
1351 }
1352
1353 $newdiscount1 = new DiscountAbsolute($this->db);
1354 $newdiscount2 = new DiscountAbsolute($this->db);
1355
1356 $newdiscount1->fk_facture_source = $discount->fk_facture_source;
1357 $newdiscount2->fk_facture_source = $discount->fk_facture_source;
1358 $newdiscount1->fk_facture = $discount->fk_facture;
1359 $newdiscount2->fk_facture = $discount->fk_facture;
1360 $newdiscount1->fk_facture_line = $discount->fk_facture_line;
1361 $newdiscount2->fk_facture_line = $discount->fk_facture_line;
1362 $newdiscount1->fk_invoice_supplier_source = $discount->fk_invoice_supplier_source;
1363 $newdiscount2->fk_invoice_supplier_source = $discount->fk_invoice_supplier_source;
1364 $newdiscount1->fk_invoice_supplier = $discount->fk_invoice_supplier;
1365 $newdiscount2->fk_invoice_supplier = $discount->fk_invoice_supplier;
1366 $newdiscount1->fk_invoice_supplier_line = $discount->fk_invoice_supplier_line;
1367 $newdiscount2->fk_invoice_supplier_line = $discount->fk_invoice_supplier_line;
1368 if ($discount->description == '(CREDIT_NOTE)' || $discount->description == '(DEPOSIT)') {
1369 $newdiscount1->description = $discount->description;
1370 $newdiscount2->description = $discount->description;
1371 } else {
1372 $newdiscount1->description = $discount->description.' (1)';
1373 $newdiscount2->description = $discount->description.' (2)';
1374 }
1375
1376 $newdiscount1->fk_user = $discount->fk_user;
1377 $newdiscount2->fk_user = $discount->fk_user;
1378 $newdiscount1->fk_soc = $discount->fk_soc;
1379 $newdiscount1->socid = $discount->socid;
1380 $newdiscount2->fk_soc = $discount->fk_soc;
1381 $newdiscount2->socid = $discount->socid;
1382 $newdiscount1->discount_type = $discount->discount_type;
1383 $newdiscount2->discount_type = $discount->discount_type;
1384 $newdiscount1->datec = $discount->datec;
1385 $newdiscount2->datec = $discount->datec;
1386 $newdiscount1->tva_tx = $discount->tva_tx;
1387 $newdiscount2->tva_tx = $discount->tva_tx;
1388 $newdiscount1->vat_src_code = $discount->vat_src_code;
1389 $newdiscount2->vat_src_code = $discount->vat_src_code;
1390 $newdiscount1->amount_ttc = $amount_ttc_1;
1391 $newdiscount2->amount_ttc = price2num($discount->amount_ttc - $newdiscount1->amount_ttc);
1392 $newdiscount1->amount_ht = price2num($newdiscount1->amount_ttc / (1 + $newdiscount1->tva_tx / 100), 'MT');
1393 $newdiscount2->amount_ht = price2num($newdiscount2->amount_ttc / (1 + $newdiscount2->tva_tx / 100), 'MT');
1394 $newdiscount1->amount_tva = price2num($newdiscount1->amount_ttc - $newdiscount1->amount_ht);
1395 $newdiscount2->amount_tva = price2num($newdiscount2->amount_ttc - $newdiscount2->amount_ht);
1396
1397 $newdiscount1->multicurrency_amount_ttc = (float) $amount_ttc_1 * ($discount->multicurrency_amount_ttc / $discount->amount_ttc);
1398 $newdiscount2->multicurrency_amount_ttc = price2num($discount->multicurrency_amount_ttc - $newdiscount1->multicurrency_amount_ttc);
1399 $newdiscount1->multicurrency_amount_ht = price2num($newdiscount1->multicurrency_amount_ttc / (1 + $newdiscount1->tva_tx / 100), 'MT');
1400 $newdiscount2->multicurrency_amount_ht = price2num($newdiscount2->multicurrency_amount_ttc / (1 + $newdiscount2->tva_tx / 100), 'MT');
1401 $newdiscount1->multicurrency_amount_tva = price2num($newdiscount1->multicurrency_amount_ttc - $newdiscount1->multicurrency_amount_ht);
1402 $newdiscount2->multicurrency_amount_tva = price2num($newdiscount2->multicurrency_amount_ttc - $newdiscount2->multicurrency_amount_ht);
1403
1404 // 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
1405 // the same for multicurrency_amount_xxx and multicurrency_total_xxx
1406 $newdiscount1->total_ttc = (float) price2num($newdiscount1->amount_ttc);
1407 $newdiscount1->total_ht = (float) price2num($newdiscount1->amount_ht);
1408 $newdiscount1->total_tva = (float) price2num($newdiscount1->amount_tva);
1409 $newdiscount2->total_ttc = (float) price2num($newdiscount2->amount_ttc);
1410 $newdiscount2->total_ht = (float) price2num($newdiscount2->amount_ht);
1411 $newdiscount2->total_tva = (float) price2num($newdiscount2->amount_tva);
1412 $newdiscount1->multicurrency_total_ttc = (float) price2num($newdiscount1->multicurrency_amount_ttc);
1413 $newdiscount1->multicurrency_total_ht = (float) price2num($newdiscount1->multicurrency_amount_ht);
1414 $newdiscount1->multicurrency_total_tva = (float) price2num($newdiscount1->multicurrency_amount_tva);
1415 $newdiscount2->multicurrency_total_ttc = (float) price2num($newdiscount2->multicurrency_amount_ttc);
1416 $newdiscount2->multicurrency_total_ht = (float) price2num($newdiscount2->multicurrency_amount_ht);
1417 $newdiscount2->multicurrency_total_tva = (float) price2num($newdiscount2->multicurrency_amount_tva);
1418
1419 $this->db->begin();
1420
1421 $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
1422 // 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
1423 $discount->fk_invoice_supplier_source = 0;
1424 $res = $discount->delete(DolibarrApiAccess::$user);
1425 $newid1 = $newdiscount1->create(DolibarrApiAccess::$user);
1426 $newid2 = $newdiscount2->create(DolibarrApiAccess::$user);
1427 if ($res <= 0 || $newid1 <= 0 || $newid2 <= 0) {
1428 $this->db->rollback();
1429 throw new RestException(500, 'Operation fail');
1430 }
1431
1432 $this->db->commit();
1433
1434 $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";
1435 $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re, ".MAIN_DB_PREFIX."facture as f";
1436 $sql .= " WHERE re.rowid IN ( $newid1, $newid2 ) AND f.rowid = re.fk_facture_source AND re.fk_soc = ".((int) $id);
1437
1438 $sql .= $this->db->order("f.type", "ASC");
1439
1440 $result = $this->db->query($sql);
1441 if (!$result) {
1442 throw new RestException(503, $this->db->lasterror());
1443 } else {
1444 // $num = $this->db->num_rows($result);
1445 while ($obj = $this->db->fetch_object($result)) {
1446 $obj_ret[] = $obj;
1447 }
1448 }
1449
1450 return $obj_ret;
1451 }
1452
1453
1472 {
1473 if (!DolibarrApiAccess::$user->hasRight('facture', 'lire')) {
1474 throw new RestException(403);
1475 }
1476 if (empty($id)) {
1477 throw new RestException(400, 'Thirdparty ID is mandatory');
1478 }
1479
1480 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1481 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1482 }
1483
1484 /*$result = $this->thirdparty->fetch($id);
1485 if( ! $result ) {
1486 throw new RestException(404, 'Thirdparty not found');
1487 }*/
1488
1489 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
1490 $invoice = new Facture($this->db);
1491 $result = $invoice->list_replacable_invoices($id);
1492 if ($result < 0) {
1493 throw new RestException(405, $invoice->error);
1494 }
1495
1496 return $result;
1497 }
1498
1521 {
1522 if (!DolibarrApiAccess::$user->hasRight('facture', 'lire')) {
1523 throw new RestException(403);
1524 }
1525 if (empty($id)) {
1526 throw new RestException(400, 'Thirdparty ID is mandatory');
1527 }
1528
1529 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1530 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1531 }
1532
1533 /*$result = $this->thirdparty->fetch($id);
1534 if( ! $result ) {
1535 throw new RestException(404, 'Thirdparty not found');
1536 }*/
1537
1538 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
1539 $invoice = new Facture($this->db);
1540 $result = $invoice->list_qualified_avoir_invoices($id);
1541 if (!is_array($result) && $result < 0) {
1542 throw new RestException(405, $invoice->error);
1543 }
1544
1545 return $result;
1546 }
1547
1564 {
1565 if (empty($id)) {
1566 throw new RestException(400, 'Thirdparty ID is mandatory');
1567 }
1568 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
1569 throw new RestException(403);
1570 }
1571 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1572 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1573 }
1574
1579 $sql = "SELECT rowid as id, fk_action as event, fk_soc as socid, fk_contact as contact_id, type, datec, tms";
1580 $sql .= " FROM ".MAIN_DB_PREFIX."notify_def";
1581 if ($id) {
1582 $sql .= " WHERE fk_soc = ".((int) $id);
1583 }
1584
1585 $result = $this->db->query($sql);
1586 if ($this->db->num_rows($result) == 0) {
1587 throw new RestException(404, 'Notification not found');
1588 }
1589
1590 $i = 0;
1591
1592 $notifications = array();
1593
1594 if ($result) {
1595 $i = 0;
1596 $num = $this->db->num_rows($result);
1597 //$min = min($num, ($limit <= 0 ? $num : $limit));
1598 $min = $num;
1599 while ($i < $min) {
1600 $obj = $this->db->fetch_object($result);
1601 $notifications[] = $obj;
1602 $i++;
1603 }
1604 } else {
1605 throw new RestException(404, 'No notifications found');
1606 }
1607
1608 $fields = array('id', 'socid', 'event', 'contact_id', 'datec', 'tms', 'type');
1609
1610 $returnNotifications = array();
1611
1612 foreach ($notifications as $notification) {
1613 $object = array();
1614 foreach ($notification as $key => $value) {
1615 if (in_array($key, $fields)) {
1616 $object[$key] = $value;
1617 }
1618 }
1619 $returnNotifications[] = $object;
1620 }
1621
1622 // Too complex for phan ?: @phan-suppress-next-line PhanTypeMismatchReturn
1623 return $returnNotifications;
1624 }
1625
1642 public function createCompanyNotification($id, $request_data = null)
1643 {
1644 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
1645 throw new RestException(403, "User has no right to update thirdparties");
1646 }
1647 if ($this->company->fetch($id) <= 0) {
1648 throw new RestException(404, 'Error creating Thirdparty Notification, Thirdparty doesn\'t exists');
1649 }
1650 $notification = new Notify($this->db);
1651
1652 $notification->socid = $id;
1653
1654 foreach ($request_data as $field => $value) {
1655 $notification->$field = $this->_checkValForAPI($field, $value, $notification);
1656 }
1657
1658 $event = $notification->event;
1659 if (!$event) {
1660 throw new RestException(500, 'Error creating Thirdparty Notification, request_data missing event');
1661 }
1662 $socid = $notification->socid;
1663 $contact_id = $notification->contact_id;
1664
1665 $exists_sql = "SELECT rowid, fk_action as event, fk_soc as socid, fk_contact as contact_id, type, datec, tms as datem";
1666 $exists_sql .= " FROM ".MAIN_DB_PREFIX."notify_def";
1667 $exists_sql .= " WHERE fk_action = '".$this->db->escape((string) $event)."'";
1668 $exists_sql .= " AND fk_soc = '".$this->db->escape((string) $socid)."'";
1669 $exists_sql .= " AND fk_contact = '".$this->db->escape((string) $contact_id)."'";
1670
1671 $exists_result = $this->db->query($exists_sql);
1672 if ($this->db->num_rows($exists_result) > 0) {
1673 throw new RestException(403, 'Notification already exists');
1674 }
1675
1676 if ($notification->create(DolibarrApiAccess::$user) < 0) {
1677 throw new RestException(500, 'Error creating Thirdparty Notification');
1678 }
1679
1680 if ($notification->update(DolibarrApiAccess::$user) < 0) {
1681 throw new RestException(500, 'Error updating values');
1682 }
1683
1684 return $this->_cleanObjectDatas($notification);
1685 }
1686
1705 public function createCompanyNotificationByCode($id, $code, $request_data = null)
1706 {
1707 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
1708 throw new RestException(403, "User has no right to update thirdparties");
1709 }
1710 if ($this->company->fetch($id) <= 0) {
1711 throw new RestException(404, 'Error creating Thirdparty Notification, Thirdparty doesn\'t exists');
1712 }
1713 $notification = new Notify($this->db);
1714 $notification->socid = $id;
1715
1716 $sql = "SELECT t.rowid as id FROM ".MAIN_DB_PREFIX."c_action_trigger as t";
1717 $sql .= " WHERE t.code = '".$this->db->escape($code)."'";
1718
1719 $result = $this->db->query($sql);
1720 if ($this->db->num_rows($result) == 0) {
1721 throw new RestException(404, 'Action Trigger code not found');
1722 }
1723
1724 $notification->event = $this->db->fetch_row($result)[0];
1725 foreach ($request_data as $field => $value) {
1726 if ($field === 'event') {
1727 throw new RestException(500, 'Error creating Thirdparty Notification, request_data contains event key');
1728 }
1729 if ($field === 'fk_action') {
1730 throw new RestException(500, 'Error creating Thirdparty Notification, request_data contains fk_action key');
1731 }
1732 $notification->$field = $this->_checkValForAPI($field, $value, $notification);
1733 }
1734
1735 $event = $notification->event;
1736 $socid = $notification->socid;
1737 $contact_id = $notification->contact_id;
1738
1739 $exists_sql = "SELECT rowid, fk_action as event, fk_soc as socid, fk_contact as contact_id, type, datec, tms as datem";
1740 $exists_sql .= " FROM ".MAIN_DB_PREFIX."notify_def";
1741 $exists_sql .= " WHERE fk_action = '".$this->db->escape((string) $event)."'";
1742 $exists_sql .= " AND fk_soc = '".$this->db->escape((string) $socid)."'";
1743 $exists_sql .= " AND fk_contact = '".$this->db->escape((string) $contact_id)."'";
1744
1745 $exists_result = $this->db->query($exists_sql);
1746 if ($this->db->num_rows($exists_result) > 0) {
1747 throw new RestException(403, 'Notification already exists');
1748 }
1749
1750 if ($notification->create(DolibarrApiAccess::$user) < 0) {
1751 throw new RestException(500, 'Error creating Thirdparty Notification, are request_data well formed?');
1752 }
1753
1754 if ($notification->update(DolibarrApiAccess::$user) < 0) {
1755 throw new RestException(500, 'Error updating values');
1756 }
1757
1758 return $this->_cleanObjectDatas($notification);
1759 }
1760
1775 public function deleteCompanyNotification($id, $notification_id)
1776 {
1777 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
1778 throw new RestException(403);
1779 }
1780
1781 $notification = new Notify($this->db);
1782
1783 $notification->fetch($notification_id);
1784
1785 $socid = (int) $notification->socid;
1786
1787 if ($socid == $id) {
1788 return $notification->delete(DolibarrApiAccess::$user);
1789 } else {
1790 throw new RestException(403, "Not allowed due to bad consistency of input data");
1791 }
1792 }
1793
1811 public function updateCompanyNotification($id, $notification_id, $request_data = null)
1812 {
1813 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
1814 throw new RestException(403, "User has no right to update thirdparties");
1815 }
1816 if ($this->company->fetch($id) <= 0) {
1817 throw new RestException(404, 'Error creating Company Notification, Company doesn\'t exists');
1818 }
1819 $notification = new Notify($this->db);
1820
1821 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
1822 $notification->fetch($notification_id, $id);
1823
1824 if ($notification->socid != $id) {
1825 throw new RestException(403, "Not allowed due to bad consistency of input data");
1826 }
1827
1828 foreach ($request_data as $field => $value) {
1829 $notification->$field = $this->_checkValForAPI($field, $value, $notification);
1830 }
1831
1832 if ($notification->update(DolibarrApiAccess::$user) < 0) {
1833 throw new RestException(500, 'Error updating values');
1834 }
1835
1836 return $this->_cleanObjectDatas($notification);
1837 }
1838
1855 {
1856 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
1857 throw new RestException(403);
1858 }
1859 if (empty($id)) {
1860 throw new RestException(400, 'Thirdparty ID is mandatory');
1861 }
1862
1863 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
1864 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1865 }
1866
1871 $sql = "SELECT rowid, fk_soc, bank, number, code_banque, code_guichet, cle_rib, bic, iban_prefix as iban, domiciliation as address, proprio,";
1872 $sql .= " owner_address, default_rib, label, datec, tms as datem, rum, frstrecur";
1873 $sql .= " FROM ".MAIN_DB_PREFIX."societe_rib";
1874 if ($id) {
1875 $sql .= " WHERE fk_soc = ".((int) $id);
1876 }
1877
1878 $result = $this->db->query($sql);
1879
1880 if ($this->db->num_rows($result) == 0) {
1881 throw new RestException(404, 'Account not found');
1882 }
1883
1884 $i = 0;
1885
1886 $accounts = array();
1887
1888 if ($result) {
1889 $i = 0;
1890 $num = $this->db->num_rows($result);
1891 //$min = min($num, ($limit <= 0 ? $num : $limit));
1892 $min = $num;
1893 while ($i < $min) {
1894 $obj = $this->db->fetch_object($result);
1895
1896 $account = new CompanyBankAccount($this->db);
1897 if ($account->fetch($obj->rowid)) {
1898 $accounts[] = $account;
1899 }
1900 $i++;
1901 }
1902 } else {
1903 throw new RestException(404, 'Account not found');
1904 }
1905
1906
1907 $fields = array('socid', 'default_rib', 'frstrecur', '1000110000001', 'datec', 'datem', 'label', 'bank', 'bic', 'iban', 'id', 'rum');
1908
1909 $returnAccounts = array();
1910
1911 foreach ($accounts as $account) {
1912 $object = array();
1913 foreach ($account as $key => $value) {
1914 if (in_array($key, $fields)) {
1915 if ($key == 'iban') {
1916 $object[$key] = dolDecrypt($value);
1917 } else {
1918 $object[$key] = $value;
1919 }
1920 }
1921 }
1922 $returnAccounts[] = $object;
1923 }
1924
1925 return $returnAccounts;
1926 }
1927
1944 public function createCompanyBankAccount($id, $request_data = null)
1945 {
1946 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
1947 throw new RestException(403);
1948 }
1949 if ($this->company->fetch($id) <= 0) {
1950 throw new RestException(404, 'Error creating Company Bank account, Company doesn\'t exists');
1951 }
1952 $account = new CompanyBankAccount($this->db);
1953
1954 $account->socid = $id;
1955
1956 foreach ($request_data as $field => $value) {
1957 if ($field === 'caller') {
1958 // 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
1959 $this->company->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
1960 continue;
1961 }
1962
1963 $account->$field = $this->_checkValForAPI('extrafields', $value, $account);
1964 }
1965
1966 if ($account->create(DolibarrApiAccess::$user) < 0) {
1967 throw new RestException(500, 'Error creating Company Bank account');
1968 }
1969
1970 if (empty($account->rum)) {
1971 require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php';
1972 $prelevement = new BonPrelevement($this->db);
1973 $account->rum = $prelevement->buildRumNumber((string) $this->company->code_client, $account->datec, (string) $account->id);
1974 $account->date_rum = dol_now();
1975 }
1976
1977 if ($account->update(DolibarrApiAccess::$user) < 0) {
1978 throw new RestException(500, 'Error updating values');
1979 }
1980
1981 return $this->_cleanObjectDatas($account);
1982 }
1983
2001 public function updateCompanyBankAccount($id, $bankaccount_id, $request_data = null)
2002 {
2003 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2004 throw new RestException(403);
2005 }
2006 if ($this->company->fetch($id) <= 0) {
2007 throw new RestException(404, 'Error creating Company Bank account, Company doesn\'t exists');
2008 }
2009 $account = new CompanyBankAccount($this->db);
2010
2011 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
2012 $account->fetch($bankaccount_id, '', $id, -1, '');
2013
2014 if ($account->socid != $id) {
2015 throw new RestException(403);
2016 }
2017
2018
2019 foreach ($request_data as $field => $value) {
2020 if ($field === 'caller') {
2021 // 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
2022 $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
2023 continue;
2024 }
2025
2026 $account->$field = $this->_checkValForAPI($field, $value, $account);
2027 }
2028
2029 if (empty($account->rum)) {
2030 require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php';
2031 $prelevement = new BonPrelevement($this->db);
2032 $account->rum = $prelevement->buildRumNumber((string) $this->company->code_client, $account->datec, (string) $account->id);
2033 $account->date_rum = dol_now();
2034 }
2035
2036 if ($account->update(DolibarrApiAccess::$user) < 0) {
2037 throw new RestException(500, 'Error updating values');
2038 }
2039
2040 return $this->_cleanObjectDatas($account);
2041 }
2042
2057 public function deleteCompanyBankAccount($id, $bankaccount_id)
2058 {
2059 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2060 throw new RestException(403);
2061 }
2062
2063 $account = new CompanyBankAccount($this->db);
2064
2065 $account->fetch($bankaccount_id);
2066
2067 $socid = (int) $account->socid;
2068
2069 if ($socid == $id) {
2070 return $account->delete(DolibarrApiAccess::$user);
2071 } else {
2072 throw new RestException(403, "Not allowed due to bad consistency of input data");
2073 }
2074 }
2075
2094 public function generateBankAccountDocument($id, $companybankid = null, $model = 'sepamandate')
2095 {
2096 global $conf, $langs;
2097
2098 $langs->loadLangs(array("main", "dict", "commercial", "products", "companies", "banks", "bills", "withdrawals"));
2099
2100 if ($this->company->fetch($id) <= 0) {
2101 throw new RestException(404, 'Thirdparty not found');
2102 }
2103
2104 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2105 throw new RestException(403);
2106 }
2107
2108 $this->company->setDocModel(DolibarrApiAccess::$user, $model);
2109
2110 $this->company->fk_bank = $this->company->fk_account;
2111 // $this->company->fk_account = $this->company->fk_account;
2112
2113 $outputlangs = $langs;
2114 $newlang = '';
2115
2116 //if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) $newlang = GETPOST('lang_id', 'aZ09');
2117 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
2118 if (isset($this->company->thirdparty->default_lang)) {
2119 $newlang = $this->company->thirdparty->default_lang; // for proposal, order, invoice, ...
2120 } elseif (isset($this->company->default_lang)) {
2121 $newlang = $this->company->default_lang; // for thirdparty
2122 }
2123 }
2124 if (!empty($newlang)) {
2125 $outputlangs = new Translate("", $conf);
2126 $outputlangs->setDefaultLang($newlang);
2127 }
2128
2129 $sql = "SELECT rowid";
2130 $sql .= " FROM ".MAIN_DB_PREFIX."societe_rib";
2131 if ($id) {
2132 $sql .= " WHERE fk_soc = ".((int) $id);
2133 }
2134 if ($companybankid) {
2135 $sql .= " AND rowid = ".((int) $companybankid);
2136 }
2137
2138 $i = 0;
2139 $accounts = array();
2140
2141 $result = $this->db->query($sql);
2142 if ($result) {
2143 if ($this->db->num_rows($result) == 0) {
2144 throw new RestException(404, 'Bank account not found');
2145 }
2146
2147 $num = $this->db->num_rows($result);
2148 //$min = min($num, ($limit <= 0 ? $num : $limit));
2149 $min = $num;
2150 while ($i < $min) {
2151 $obj = $this->db->fetch_object($result);
2152
2153 $account = new CompanyBankAccount($this->db);
2154 if ($account->fetch($obj->rowid)) {
2155 $accounts[] = $account;
2156 }
2157 $i++;
2158 }
2159 } else {
2160 throw new RestException(500, 'Sql error '.$this->db->lasterror());
2161 }
2162
2163 $moreparams = array(
2164 'use_companybankid' => $accounts[0]->id,
2165 'force_dir_output' => $conf->societe->multidir_output[$this->company->entity].'/'.dol_sanitizeFileName((string) $this->company->id)
2166 );
2167
2168 $result = $this->company->generateDocument($model, $outputlangs, 0, 0, 0, $moreparams);
2169
2170 if ($result > 0) {
2171 return array("success" => $result);
2172 } else {
2173 throw new RestException(500, 'Error generating the document '.$this->company->error);
2174 }
2175 }
2176
2194 public function getSocieteAccounts($id, $site = null)
2195 {
2196 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
2197 throw new RestException(403);
2198 }
2199
2200 if (!DolibarrApi::_checkAccessToResource('societe', $id)) {
2201 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
2202 }
2203
2207 $sql = "SELECT rowid, fk_soc, key_account, site, date_creation, tms FROM ".MAIN_DB_PREFIX."societe_account";
2208 $sql .= " WHERE fk_soc = ".((int) $id);
2209 if ($site) {
2210 $sql .= " AND site ='".$this->db->escape($site)."'";
2211 }
2212
2213 $result = $this->db->query($sql);
2214
2215 if ($result && $this->db->num_rows($result) == 0) {
2216 throw new RestException(404, 'This thirdparty does not have any account attached or does not exist.');
2217 }
2218
2219 $i = 0;
2220
2221 $accounts = array();
2222
2223 $i = 0;
2224 $num = $this->db->num_rows($result);
2225 //$min = min($num, ($limit <= 0 ? $num : $limit));
2226 $min = $num;
2227 while ($i < $min) {
2228 $obj = $this->db->fetch_object($result);
2229 $account = new SocieteAccount($this->db);
2230
2231 if ($account->fetch($obj->rowid)) {
2232 $accounts[] = $account;
2233 }
2234 $i++;
2235 }
2236
2237 $fields = array('id', 'fk_soc', 'key_account', 'site', 'date_creation', 'tms');
2238
2239 $returnAccounts = array();
2240
2241 foreach ($accounts as $account) {
2242 $object = array();
2243 foreach ($account as $key => $value) {
2244 if (in_array($key, $fields)) {
2245 $object[$key] = $value;
2246 }
2247 }
2248 $returnAccounts[] = $object;
2249 }
2250
2251 return $returnAccounts;
2252 }
2253
2271 public function getSocieteByAccounts($site, $key_account)
2272 {
2273 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
2274 throw new RestException(403);
2275 }
2276
2277 $sql = "SELECT rowid, fk_soc, key_account, site, date_creation, tms FROM ".MAIN_DB_PREFIX."societe_account";
2278 $sql .= " WHERE site = '".$this->db->escape($site)."' AND key_account = '".$this->db->escape($key_account)."'";
2279 $sql .= " AND entity IN (".getEntity('societe').")";
2280
2281 $result = $this->db->query($sql);
2282
2283 if ($result && $this->db->num_rows($result) == 1) {
2284 $obj = $this->db->fetch_object($result);
2285 $returnThirdparty = $this->_fetch($obj->fk_soc);
2286 } else {
2287 throw new RestException(404, 'This account have many thirdparties attached or does not exist.');
2288 }
2289
2290 if (!DolibarrApi::_checkAccessToResource('societe', $returnThirdparty->id)) {
2291 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
2292 }
2293
2294 return $returnThirdparty;
2295 }
2296
2320 public function createSocieteAccount($id, $request_data = null)
2321 {
2322 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2323 throw new RestException(403);
2324 }
2325
2326 if (!isset($request_data['site'])) {
2327 throw new RestException(422, 'Unprocessable Entity: You must pass the site attribute in your request data !');
2328 }
2329
2330 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = ".((int) $id)." AND site = '".$this->db->escape($request_data['site'])."'";
2331 $result = $this->db->query($sql);
2332
2333 if ($result && $this->db->num_rows($result) == 0) {
2334 $account = new SocieteAccount($this->db);
2335 if (!isset($request_data['login'])) {
2336 $account->login = "";
2337 }
2338 $account->fk_soc = $id;
2339
2340 foreach ($request_data as $field => $value) {
2341 if ($field === 'caller') {
2342 // 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
2343 $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
2344 continue;
2345 }
2346
2347 $account->$field = $this->_checkValForAPI($field, $value, $account);
2348 }
2349
2350 if ($account->create(DolibarrApiAccess::$user) < 0) {
2351 throw new RestException(500, 'Error creating SocieteAccount entity. Ensure that the ID of thirdparty provided does exist!');
2352 }
2353
2354 $this->_cleanObjectDatas($account);
2355
2356 return $account;
2357 } else {
2358 throw new RestException(409, 'A SocieteAccount entity already exists for this company and site.');
2359 }
2360 }
2361
2388 public function postSocieteAccount($id, $site, $request_data = null)
2389 {
2390 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2391 throw new RestException(403);
2392 }
2393
2394 $sql = "SELECT rowid, fk_user_creat, date_creation FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = $id AND site = '".$this->db->escape($site)."'";
2395 $result = $this->db->query($sql);
2396
2397 // We do not found an existing SocieteAccount entity for this fk_soc and site ; we then create a new one.
2398 if ($result && $this->db->num_rows($result) == 0) {
2399 if (!isset($request_data['key_account'])) {
2400 throw new RestException(422, 'Unprocessable Entity: You must pass the key_account attribute in your request data !');
2401 }
2402 $account = new SocieteAccount($this->db);
2403 if (!isset($request_data['login'])) {
2404 $account->login = "";
2405 }
2406
2407 foreach ($request_data as $field => $value) {
2408 if ($field === 'caller') {
2409 // 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
2410 $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
2411 continue;
2412 }
2413
2414 $account->$field = $this->_checkValForAPI($field, $value, $account);
2415 }
2416
2417 $account->fk_soc = $id;
2418 $account->site = $site;
2419
2420 if ($account->create(DolibarrApiAccess::$user) < 0) {
2421 throw new RestException(500, 'Error creating SocieteAccount entity.');
2422 }
2423 // We found an existing SocieteAccount entity, we are replacing it
2424 } else {
2425 if (isset($request_data['site']) && $request_data['site'] !== $site) {
2426 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = ".((int) $id)." AND site = '".$this->db->escape($request_data['site'])."' ";
2427 $result = $this->db->query($sql);
2428
2429 if ($result && $this->db->num_rows($result) !== 0) {
2430 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.");
2431 }
2432 }
2433
2434 $obj = $this->db->fetch_object($result);
2435
2436 $account = new SocieteAccount($this->db);
2437 $account->id = $obj->rowid;
2438 $account->fk_soc = $id;
2439 $account->site = $site;
2440 if (!isset($request_data['login'])) {
2441 $account->login = "";
2442 }
2443 $account->fk_user_creat = $obj->fk_user_creat;
2444 $account->date_creation = $obj->date_creation;
2445
2446 foreach ($request_data as $field => $value) {
2447 if ($field === 'caller') {
2448 // 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
2449 $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
2450 continue;
2451 }
2452
2453 $account->$field = $this->_checkValForAPI($field, $value, $account);
2454 }
2455
2456 if ($account->update(DolibarrApiAccess::$user) < 0) {
2457 throw new RestException(500, 'Error updating SocieteAccount entity.');
2458 }
2459 }
2460
2461 $this->_cleanObjectDatas($account);
2462
2463 return $account;
2464 }
2465
2486 public function putSocieteAccount($id, $site, $request_data = null)
2487 {
2488 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2489 throw new RestException(403);
2490 }
2491
2492 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = ".((int) $id)." AND site = '".$this->db->escape($site)."'";
2493 $result = $this->db->query($sql);
2494
2495 if ($result && $this->db->num_rows($result) == 0) {
2496 throw new RestException(404, "This thirdparty does not have $site account attached or does not exist.");
2497 } else {
2498 // If the user tries to edit the site member, we check first if
2499 if (isset($request_data['site']) && $request_data['site'] !== $site) {
2500 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = ".((int) $id)." AND site = '".$this->db->escape($request_data['site'])."' ";
2501 $result = $this->db->query($sql);
2502
2503 if ($result && $this->db->num_rows($result) !== 0) {
2504 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.");
2505 }
2506 }
2507
2508 $obj = $this->db->fetch_object($result);
2509 $account = new SocieteAccount($this->db);
2510 $account->fetch($obj->rowid);
2511
2512 foreach ($request_data as $field => $value) {
2513 if ($field === 'caller') {
2514 // 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
2515 $account->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
2516 continue;
2517 }
2518
2519 $account->$field = $this->_checkValForAPI($field, $value, $account);
2520 }
2521
2522 if ($account->update(DolibarrApiAccess::$user) < 0) {
2523 throw new RestException(500, 'Error updating SocieteAccount account');
2524 }
2525
2526 $this->_cleanObjectDatas($account);
2527
2528 return $account;
2529 }
2530 }
2531
2550 public function deleteSocieteAccount($id, $site)
2551 {
2552 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2553 throw new RestException(403);
2554 }
2555
2556 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = $id AND site = '".$this->db->escape($site)."'";
2557 $result = $this->db->query($sql);
2558
2559 if ($result && $this->db->num_rows($result) == 0) {
2560 throw new RestException(404);
2561 } else {
2562 $obj = $this->db->fetch_object($result);
2563 $account = new SocieteAccount($this->db);
2564 $account->fetch($obj->rowid);
2565
2566 if ($account->delete(DolibarrApiAccess::$user) < 0) {
2567 throw new RestException(500, "Error while deleting $site account attached to this third party");
2568 }
2569 }
2570 }
2571
2588 {
2589 if (!DolibarrApiAccess::$user->hasRight('societe', 'creer')) {
2590 throw new RestException(403);
2591 }
2592
2597 $sql = "SELECT rowid, fk_soc, key_account, site, date_creation, tms";
2598 $sql .= " FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = ".((int) $id);
2599
2600 $result = $this->db->query($sql);
2601
2602 if ($result && $this->db->num_rows($result) == 0) {
2603 throw new RestException(404, 'This third party does not have any account attached or does not exist.');
2604 } else {
2605 $i = 0;
2606
2607 $i = 0;
2608 $num = $this->db->num_rows($result);
2609 //$min = min($num, ($limit <= 0 ? $num : $limit));
2610 $min = $num;
2611 while ($i < $min) {
2612 $obj = $this->db->fetch_object($result);
2613 $account = new SocieteAccount($this->db);
2614 $account->fetch($obj->rowid);
2615
2616 if ($account->delete(DolibarrApiAccess::$user) < 0) {
2617 throw new RestException(500, 'Error while deleting account attached to this third party');
2618 }
2619 $i++;
2620 }
2621 }
2622 }
2623
2624 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2634 protected function _cleanObjectDatas($object)
2635 {
2636 // phpcs:enable
2637 $object = parent::_cleanObjectDatas($object);
2638
2639 unset($object->nom); // ->name already defined and nom deprecated
2640 unset($object->name_bis); // ->name_alias already defined
2641 unset($object->note); // ->note_private and note_public already defined
2642 unset($object->departement);
2643 unset($object->departement_code);
2644 unset($object->pays);
2645 unset($object->particulier);
2646 unset($object->prefix_comm);
2647
2648 unset($object->siren);
2649 unset($object->siret);
2650 unset($object->ape);
2651
2652 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.
2653
2654 unset($object->total_ht);
2655 unset($object->total_tva);
2656 unset($object->total_localtax1);
2657 unset($object->total_localtax2);
2658 unset($object->total_ttc);
2659
2660 unset($object->lines);
2661 unset($object->thirdparty);
2662
2663 unset($object->fk_delivery_address); // deprecated feature
2664
2665 return $object;
2666 }
2667
2676 private function _validate($data)
2677 {
2678 if ($data === null) {
2679 $data = array();
2680 }
2681 $thirdparty = array();
2682 foreach (Thirdparties::$FIELDS as $field) {
2683 if (!isset($data[$field])) {
2684 throw new RestException(400, "$field field missing");
2685 }
2686 $thirdparty[$field] = $data[$field];
2687 }
2688 return $thirdparty;
2689 }
2690
2714 private function _fetch($rowid, $ref = '', $ref_ext = '', $barcode = '', $idprof1 = '', $idprof2 = '', $idprof3 = '', $idprof4 = '', $idprof5 = '', $idprof6 = '', $email = '', $ref_alias = '')
2715 {
2716 if (!DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
2717 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login.'. No read permission on thirdparties.');
2718 }
2719
2720 if ($rowid === 0) {
2721 $result = $this->company->initAsSpecimen();
2722 } else {
2723 $result = $this->company->fetch((int) $rowid, $ref, $ref_ext, $barcode, $idprof1, $idprof2, $idprof3, $idprof4, $idprof5, $idprof6, $email, $ref_alias);
2724 }
2725 if (!$result) {
2726 throw new RestException(404, 'Thirdparty not found');
2727 }
2728
2729 if (!DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
2730 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login.' on this thirdparty');
2731 }
2732 if (isModEnabled('mailing')) {
2733 $this->company->getNoEmail();
2734 }
2735
2736 if (getDolGlobalString('FACTURE_DEPOSITS_ARE_JUST_PAYMENTS')) {
2737 $filterabsolutediscount = "fk_facture_source IS NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
2738 $filtercreditnote = "fk_facture_source IS NOT NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
2739 } else {
2740 $filterabsolutediscount = "fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')";
2741 $filtercreditnote = "fk_facture_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%')";
2742 }
2743
2744 $absolute_discount = $this->company->getAvailableDiscounts(null, $filterabsolutediscount);
2745 $absolute_creditnote = $this->company->getAvailableDiscounts(null, $filtercreditnote);
2746 $this->company->absolute_discount = price2num($absolute_discount, 'MT');
2747 $this->company->absolute_creditnote = price2num($absolute_creditnote, 'MT');
2748
2749 return $this->_cleanObjectDatas($this->company);
2750 }
2751}
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
Class to manage withdrawal receipts.
Class to manage categories.
Class to manage bank accounts description of third parties.
Class to manage absolute discounts.
Class for API REST v1.
Definition api.class.php:35
_checkValExtrafieldsForAPI($field, $value, $object)
Check and convert a string depending on its type/name.
_filterObjectProperties($object, $properties)
Filter properties that will be returned on object.
static _checkAccessToResource($resource, $resource_id=0, $dbtablename='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid')
Check access by user to a given resource.
_checkValForAPI($field, $value, $object)
Check and convert a string depending on its type/name.
Class to manage invoices.
Class to manage the table of subscription to notifications.
Class for SocieteAccount.
Class to manage third parties objects (customers, suppliers, prospects...)
updateCompanyNotification($id, $notification_id, $request_data=null)
Update a company notification for a third party.
setThirdpartyPriceLevel($id, $priceLevel)
Set a new price level for the given third party.
_cleanObjectDatas($object)
Clean sensible object datas @phpstan-template T.
getSocieteByAccounts($site, $key_account)
Get a specific third party by account.
getSupplierCategories($id, $sortfield="s.rowid", $sortorder='ASC', $limit=0, $page=0)
Get supplier categories for a third party.
deleteCompanyNotification($id, $notification_id)
Delete a company notification attached to a third party.
getSocieteAccounts($id, $site=null)
Get a specific account attached to a third party.
getOutStandingOrder($id, $mode='customer')
Get outstanding orders for a third party.
addRepresentative($id, $representative_id)
Add a customer representative to a third party.
getByBarcode($barcode)
Get a third party by barcode.
generateBankAccountDocument($id, $companybankid=null, $model='sepamandate')
Generate a document from a bank account record.
createCompanyNotificationByCode($id, $code, $request_data=null)
Create a company notification for a third party using action trigger code.
getCompanyNotification($id)
Get company notifications for a third party.
addCategory($id, $category_id)
Add a customer category to a third party.
getCompanyBankAccount($id)
Get company bank accounts of a third party.
getInvoicesQualifiedForReplacement($id)
Return invoices qualified to be replaced by another invoice.
post($request_data=null)
Create a third party.
put($id, $request_data=null)
Update third party.
getByEmail($email)
Get properties of a third party by email.
_validate($data)
Validate fields before create or update object.
getFixedAmountDiscounts($id, $mode='customer', $filter="none", $sortfield="f.type", $sortorder='ASC')
Get fixed amount discount of a third party.
addSupplierCategory($id, $category_id)
Add a supplier category to a third party.
merge($id, $idtodelete)
Merge a third party into another third party.
deleteSocieteAccounts($id)
Delete all accounts attached to a third party.
__construct()
Constructor.
getCategories($id, $sortfield="s.rowid", $sortorder='ASC', $limit=0, $page=0)
Get customer categories for a third party.
postSocieteAccount($id, $site, $request_data=null)
Create and attach a new (or replace an existing) specific site account for a third party.
deleteSupplierCategory($id, $category_id)
Remove the link between a category and the third party.
createFixedAmountDiscount($id, $request_data=null)
Create a fixed amount discount for a thirdparty.
deleteRepresentative($id, $representative_id)
Remove the link between a customer representative and a third party.
createCompanyNotification($id, $request_data=null)
Create a company notification for a third party.
putSocieteAccount($id, $site, $request_data=null)
Update specified values of a specific account attached to a third party.
updateCompanyBankAccount($id, $bankaccount_id, $request_data=null)
Update a company bank account of a third party.
deleteSocieteAccount($id, $site)
Delete a specific site account attached to a third party.
getInvoicesQualifiedForCreditNote($id)
Return invoices qualified to be corrected by a credit note.
getOutStandingProposals($id, $mode='customer')
Get outstanding proposals for a third party.
_fetch($rowid, $ref='', $ref_ext='', $barcode='', $idprof1='', $idprof2='', $idprof3='', $idprof4='', $idprof5='', $idprof6='', $email='', $ref_alias='')
Fetch properties of a thirdparty object.
getSalesRepresentatives($id, $mode=0)
Get representatives of a third party.
getOutStandingInvoices($id, $mode='customer')
Get outstanding invoices for a third party.
splitdiscount($id, $discountid, $amount_ttc_1, $amount_ttc_2)
Split a discount in 2 smaller discount.
index($sortfield="t.rowid", $sortorder='ASC', $limit=100, $page=0, $mode=0, $category=0, $sqlfilters='', $properties='', $pagination_data=false)
List third parties.
deleteCompanyBankAccount($id, $bankaccount_id)
Delete a bank account attached to a third party.
createSocieteAccount($id, $request_data=null)
Create and attach a new account to an existing third party.
createCompanyBankAccount($id, $request_data=null)
Create a company bank account for a third party.
deleteCategory($id, $category_id)
Remove the link between a customer category and the third party.
Class to manage translations.
Class to manage Dolibarr users.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
dol_now($mode='gmt')
Return date for now.
dol_getIdFromCode($db, $key, $tablename, $fieldkey='code', $fieldid='id', $entityfilter=0, $filters='', $useCache=true)
Return an id or code from a code or id.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
sanitizeVal($out='', $check='alphanohtml', $filter=null, $options=null)
Return a sanitized or empty value after checking value against a rule.
isModEnabled($module)
Is Dolibarr module enabled.
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php
dolDecrypt($chain, $key='', $patterntotest='')
Decode a string with a symmetric encryption.