25require_once DOL_DOCUMENT_ROOT .
'/societe/class/societe.class.php';
26require_once DOL_DOCUMENT_ROOT .
'/contact/class/contact.class.php';
58 "name" =>
"search_thirdparties",
59 "description" =>
"Search for a thirdparty by ID, name, alias, code, or email. If a numerical ID is provided alone, it returns an exact match. If a name is provided, it returns a list of matches.",
63 "query" => [
"type" => [
"string",
"integer"],
"description" =>
"The ID of the thirdparty, or a name/alias/code/email to search for."],
64 "type" => [
"type" =>
"string",
"enum" => [
"customer",
"prospect",
"supplier"],
"description" =>
"Filter by type (optional)."],
65 "country_code" => [
"type" =>
"string",
"description" =>
"ISO 2-letter country code (e.g. US, FR, GR) (optional)."],
66 "limit" => [
"type" =>
"integer",
"default" => 5]
68 "required" => [
"query"]
72 "name" =>
"count_thirdparties",
73 "description" =>
"Count the number of thirdparties matching the search criteria.",
77 "query" => [
"type" => [
"string",
"integer"],
"description" =>
"A name/alias/code/email to search for."],
78 "type" => [
"type" =>
"string",
"enum" => [
"customer",
"prospect",
"supplier"],
"description" =>
"Filter by type (optional)."],
79 "country_code" => [
"type" =>
"string",
"description" =>
"ISO 2-letter country code (e.g. US, FR, GR) (optional)."]
81 "required" => [
"query"]
85 "name" =>
"get_thirdparty_details",
86 "description" =>
"Get full details of a specific thirdparty by ID.",
90 "id" => [
"type" =>
"integer",
"description" =>
"The unique numerical ID of the thirdparty."]
96 "name" =>
"create_thirdparty",
97 "description" =>
"Create a new thirdparty (Using only terms: Customer, Prospect, or Supplier).",
101 "name" => [
"type" =>
"string",
"description" =>
"Name of the thirdparty"],
102 "type" => [
"type" =>
"string",
"enum" => [
"customer",
"prospect",
"supplier",
"both",
"none"],
"default" =>
"customer",
"description" =>
"Type of thirdparty. 'none' means not a customer or prospect."],
103 "email" => [
"type" =>
"string",
"description" =>
"Email address"],
104 "phone" => [
"type" =>
"string",
"description" =>
"Phone number"],
105 "address" => [
"type" =>
"string",
"description" =>
"Address"],
106 "zip" => [
"type" =>
"string",
"description" =>
"Postal code"],
107 "town" => [
"type" =>
"string",
"description" =>
"Town/City"],
108 "country_code" => [
"type" =>
"string",
"description" =>
"ISO 2-letter country code (e.g. US, FR, GR)"],
109 "code_client" => [
"type" =>
"string",
"description" =>
"Customer code (optional, -1 for auto-generation)"],
110 "idprof1" => [
"type" =>
"string",
"description" =>
"Professional ID 1"],
111 "idprof2" => [
"type" =>
"string",
"description" =>
"Professional ID 2"],
112 "idprof3" => [
"type" =>
"string",
"description" =>
"Professional ID 3"],
113 "idprof4" => [
"type" =>
"string",
"description" =>
"Professional ID 4"]
115 "required" => [
"name"]
119 "name" =>
"update_thirdparty",
120 "description" =>
"Updates an existing thirdparty's details.",
124 "id" => [
"type" =>
"integer",
"description" =>
"The ID of the thirdparty to update."],
125 "name" => [
"type" =>
"string",
"description" =>
"The new name for the thirdparty."],
126 "email" => [
"type" =>
"string",
"description" =>
"The new email address."],
127 "phone" => [
"type" =>
"string",
"description" =>
"The new phone number."],
128 "address" => [
"type" =>
"string",
"description" =>
"The new address."],
129 "zip" => [
"type" =>
"string",
"description" =>
"The new postal code."],
130 "town" => [
"type" =>
"string",
"description" =>
"The new town."],
131 "country_code" => [
"type" =>
"string",
"description" =>
"The new ISO 2-letter country code."]
137 "name" =>
"list_thirdparty_contacts",
138 "description" =>
"Lists all contacts associated with a specific thirdparty.",
142 "id" => [
"type" =>
"integer",
"description" =>
"The ID of the thirdparty."]
148 "name" =>
"add_thirdparty_contact",
149 "description" =>
"Adds a new contact to an existing thirdparty.",
153 "thirdparty_identifier" => [
154 "type" => [
"string",
"integer"],
155 "description" =>
"The ID or name of the thirdparty to add the contact to."
157 "firstname" => [
"type" =>
"string",
"description" =>
"Contact's first name."],
158 "lastname" => [
"type" =>
"string",
"description" =>
"Contact's last name."],
159 "email" => [
"type" =>
"string",
"description" =>
"Contact's email address."],
160 "phone" => [
"type" =>
"string",
"description" =>
"Contact's phone number."],
161 "role" => [
"type" =>
"string",
"description" =>
"Contact's role or position within the company."]
163 "required" => [
"thirdparty_identifier",
"firstname",
"lastname"]
177 return [
'thirdparty',
'billing',
'commercial',
'project',
'stock'];
187 public function execute(
string $name, array $args)
190 case 'search_thirdparties':
191 return $this->
search($args, 0);
192 case 'count_thirdparties':
193 return $this->
search($args, 1);
194 case 'get_thirdparty_details':
196 case 'create_thirdparty':
197 return $this->create($args);
198 case 'update_thirdparty':
199 return $this->update($args);
200 case 'list_thirdparty_contacts':
202 case 'add_thirdparty_contact':
205 return [
"error" =>
"Tool function '$name' not found."];
220 private function search(array $args,
int $count = 0)
222 if (!$this->
user->hasRight(
'societe',
'lire')) {
223 return [
"error" =>
"Permission Denied"];
226 $query = $args[
'query'];
227 $type = isset($args[
'type']) ? (
string) $args[
'type'] :
'';
228 $country_code = isset($args[
'country_code']) ? (
string) $args[
'country_code'] :
'';
229 $limit = isset($args[
'limit']) ? (int) $args[
'limit'] : 5;
236 dol_syslog(
"Search DB Error: Too many record requested", LOG_ERR);
237 return [
"error" =>
"DB Error"];
242 $sql =
"SELECT COUNT(s.rowid) as nb";
244 $sql =
"SELECT s.rowid, s.nom, s.name_alias, s.code_client, s.code_fournisseur, s.email, s.client, s.fournisseur";
246 $sql .=
" FROM " . MAIN_DB_PREFIX .
"societe as s";
248 $sql.=
" INNER JOIN ".MAIN_DB_PREFIX.
"c_country as c ON s.fk_pays = c.rowid AND c.code = '".$this->db->escape($country_code).
"'";
250 $sql .=
" WHERE s.entity IN (" .
getEntity(
'societe') .
")";
252 if (is_numeric($query)) {
253 $sql .=
" AND s.rowid = " . (int) $query;
256 $sql .=
" AND (s.nom LIKE '%" . $this->db->escape($query) .
"%'";
257 $sql .=
" OR s.name_alias LIKE '%" . $this->db->escape($query) .
"%'";
258 $sql .=
" OR s.code_client LIKE '%" . $this->db->escape($query) .
"%'";
259 $sql .=
" OR s.code_fournisseur LIKE '%" . $this->db->escape($query) .
"%'";
260 $sql .=
" OR s.email LIKE '%" . $this->db->escape($query) .
"%')";
263 if ($type ===
'customer') {
264 $sql .=
" AND s.client IN (1, 3)";
265 } elseif ($type ===
'prospect') {
266 $sql .=
" AND s.client IN (2, 3)";
267 } elseif ($type ===
'supplier') {
268 $sql .=
" AND s.fournisseur = 1";
271 $sql .=
" ORDER BY s.nom ASC";
272 $sql .= $this->db->plimit($limit);
274 $resql = $this->db->query($sql);
277 dol_syslog(
"Search DB Error: " . $this->db->lasterror(), LOG_ERR);
278 return [
"error" =>
"DB Error"];
283 while ($obj = $this->db->fetch_object($resql)) {
286 "count" => (int) $obj->nb
289 $this->db->free($resql);
297 $is_client = (int) $obj->client;
298 $is_supplier = (int) $obj->fournisseur;
300 if ($is_client === 1 || $is_client === 3) {
301 $roles[] =
"Customer";
303 if ($is_client === 2 || $is_client === 3) {
304 $roles[] =
"Prospect";
306 if ($is_supplier === 1) {
307 $roles[] =
"Supplier";
311 "id" => (int) $obj->rowid,
312 "name" => (
string) $obj->nom,
313 "alias" => (
string) $obj->name_alias,
314 "code_cust" => (
string) $obj->code_client,
315 "code_sup" => (
string) $obj->code_fournisseur,
316 "email" => (
string) $obj->email,
317 "type" => implode(
'/', $roles),
318 "url" => DOL_URL_ROOT .
"/societe/card.php?socid=" . $obj->rowid
322 $this->db->free($resql);
337 if (!$this->
user->hasRight(
'societe',
'lire')) {
338 return [
"error" =>
"Permission Denied"];
341 if (empty($args[
'id'])) {
342 return [
"error" =>
"ID is required"];
348 $result = $soc->fetch((
int) $args[
'id']);
352 "id" => (int) $soc->id,
353 "name" => (
string) $soc->nom,
354 "address" => (
string) $soc->address,
355 "zip" => (
string) $soc->zip,
356 "city" => (
string) $soc->town,
357 "country" => (
string) $soc->country,
358 "email" => (
string) $soc->email,
359 "phone" => (
string) $soc->phone,
360 "vat" => (
string) $soc->tva_intra,
362 "status" => (
string) $soc->getLibStatut(2),
363 "url" => DOL_URL_ROOT .
"/societe/card.php?socid=" . $soc->id
367 return [
"error" =>
"Thirdparty not found"];
379 private function create(array $args)
384 if (!$this->
user->hasRight(
'societe',
'creer')) {
385 return [
"error" =>
"Permission Denied"];
389 if (empty($args[
'name'])) {
390 return [
"error" =>
"Name is required"];
396 $soc->nom = (
string) $args[
'name'];
397 $soc->email = isset($args[
'email']) ? (
string) $args[
'email'] :
'';
398 $soc->phone = isset($args[
'phone']) ? (
string) $args[
'phone'] :
'';
399 $soc->address = isset($args[
'address']) ? (
string) $args[
'address'] :
'';
400 $soc->zip = isset($args[
'zip']) ? (
string) $args[
'zip'] :
'';
401 $soc->town = isset($args[
'town']) ? (
string) $args[
'town'] :
'';
402 $soc->code_client = isset($args[
'code_client']) ? (
string) $args[
'code_client'] :
'';
403 $soc->idprof1 = isset($args[
'idprof1']) ? (
string) $args[
'idprof1'] :
'';
404 $soc->idprof2 = isset($args[
'idprof2']) ? (
string) $args[
'idprof2'] :
'';
405 $soc->idprof3 = isset($args[
'idprof3']) ? (
string) $args[
'idprof3'] :
'';
406 $soc->idprof4 = isset($args[
'idprof4']) ? (
string) $args[
'idprof4'] :
'';
409 if (! empty($args[
'country_code'])) {
410 require_once DOL_DOCUMENT_ROOT .
'/core/lib/company.lib.php';
413 $info =
getCountry($args[
'country_code'],
'1');
414 if ($info && isset($info[
'id'])) {
415 $soc->country_id = (int) $info[
'id'];
420 if (empty($soc->country_id) && !empty(
$conf->global->MAIN_INFO_SOCIETE_COUNTRY)) {
421 $soc->country_id = (int)
$conf->global->MAIN_INFO_SOCIETE_COUNTRY;
424 $type = $args[
'type'] ??
'customer';
426 $soc->fournisseur = 0;
428 if ($type ===
'customer') {
430 if (empty($soc->code_client)) {
431 $soc->code_client =
'-1';
433 } elseif ($type ===
'prospect') {
435 if (empty($soc->code_client)) {
436 $soc->code_client =
'-1';
438 } elseif ($type ===
'both') {
440 if (empty($soc->code_client)) {
441 $soc->code_client =
'-1';
445 if ($type ===
'supplier' || $type ===
'both') {
446 $soc->fournisseur = 1;
447 if (empty($soc->code_fournisseur)) {
448 $soc->code_fournisseur =
'-1';
452 $result = $soc->create($this->
user);
456 "status" =>
"success",
457 "message" =>
"Thirdparty created",
458 "id" => (int) $soc->id,
459 "name" => (
string) $soc->name,
460 "url" => DOL_URL_ROOT .
"/societe/card.php?socid=" . $soc->id
464 return [
"error" =>
"Create failed: " . (
string) $soc->error];
475 private function update(array $args)
477 if (!$this->
user->hasRight(
'societe',
'creer') && !$this->user->hasRight(
'societe',
'modifier')) {
478 return [
"error" =>
"Permission Denied to update."];
481 if (empty($args[
'id'])) {
482 return [
"error" =>
"ID is required for update."];
487 $result = $soc->fetch((
int) $args[
'id']);
489 return [
"error" =>
"Thirdparty not found with ID: " . $args[
'id']];
494 if (isset($args[
'name'])) {
495 $soc->nom = (
string) $args[
'name'];
497 if (isset($args[
'email'])) {
498 $soc->email = (
string) $args[
'email'];
500 if (isset($args[
'phone'])) {
501 $soc->phone = (
string) $args[
'phone'];
503 if (isset($args[
'address'])) {
504 $soc->address = (
string) $args[
'address'];
506 if (isset($args[
'zip'])) {
507 $soc->zip = (
string) $args[
'zip'];
509 if (isset($args[
'town'])) {
510 $soc->town = (
string) $args[
'town'];
514 if (!empty($args[
'country_code'])) {
515 require_once DOL_DOCUMENT_ROOT .
'/core/lib/company.lib.php';
518 $info =
getCountry($args[
'country_code'],
'1');
520 if ($info && isset($info[
'id'])) {
521 $soc->country_id = (int) $info[
'id'];
525 if ($soc->update($soc->id, $this->user) > 0) {
527 "status" =>
"success",
528 "message" =>
"Thirdparty updated successfully.",
529 "id" => (int) $soc->id,
530 "url" => DOL_URL_ROOT .
"/societe/card.php?socid=" . $soc->id
534 return [
"error" =>
"Update failed: " . (
string) $soc->error];
549 if (!$this->
user->hasRight(
'societe',
'lire')) {
550 return [
"error" =>
"Permission Denied"];
553 if (empty($args[
'id'])) {
554 return [
"error" =>
"Thirdparty ID is required"];
557 $socid = (int) $args[
'id'];
558 $langs->load(
"companies");
559 $langs->load(
"other");
562 $label_id = $langs->transnoentitiesnoconv(
"Id");
563 $label_firstname = $langs->transnoentitiesnoconv(
"Firstname");
564 $label_lastname = $langs->transnoentitiesnoconv(
"Lastname");
565 $label_email = $langs->transnoentitiesnoconv(
"Email");
566 $label_phone = $langs->transnoentitiesnoconv(
"Phone");
567 $label_role = $langs->transnoentitiesnoconv(
"PostOrFunction");
568 $label_link = $langs->transnoentitiesnoconv(
"Link");
570 $link_text = $langs->transnoentitiesnoconv(
"Show");
574 if ($soc->fetch($socid) <= 0) {
575 return [
"error" =>
"Thirdparty not found with ID: " . $socid];
579 $sql =
"SELECT t.rowid, t.firstname, t.lastname, t.email, t.phone, t.poste";
580 $sql .=
" FROM " . MAIN_DB_PREFIX .
"socpeople as t";
581 $sql .=
" WHERE t.fk_soc = " . (int) $socid;
582 $sql .=
" AND t.entity IN (" .
getEntity(
'socpeople') .
")";
583 $sql .=
" ORDER BY t.lastname ASC, t.firstname ASC";
585 $resql = $this->db->query($sql);
588 dol_syslog(
"DB Error in listContacts: " . $this->db->lasterror(), LOG_ERR);
589 return [
"error" =>
"DB Error"];
594 while ($obj = $this->db->fetch_object($resql)) {
596 $absoluteUrl = DOL_URL_ROOT .
"/contact/card.php?id=" . $obj->rowid;
598 $htmlLink =
"<a href='" . $absoluteUrl .
"' target='_blank'>" . $link_text .
"</a>";
601 $label_id => (int) $obj->rowid,
602 $label_firstname => (
string) $obj->firstname,
603 $label_lastname => (
string) $obj->lastname,
604 $label_email => (
string) $obj->email,
605 $label_phone => (
string) $obj->phone,
606 $label_role => (
string) $obj->poste,
607 $label_link => $htmlLink
611 $this->db->free($resql);
627 if (!$this->
user->hasRight(
'societe',
'creer')) {
628 return [
"error" =>
"Permission Denied to create contacts."];
631 if (empty($args[
'thirdparty_identifier']) || empty($args[
'firstname']) || empty($args[
'lastname'])) {
632 return [
"error" =>
"Thirdparty identifier, firstname and lastname are required."];
635 $identifier = $args[
'thirdparty_identifier'];
640 if (is_numeric($identifier)) {
642 $res = $soc->fetch((
int) $identifier);
645 $res = $soc->fetch(0, (
string) $identifier);
649 return [
"error" =>
"Thirdparty not found with identifier: " . $identifier];
653 $contact =
new Contact($this->db);
654 $contact->socid = $soc->id;
655 $contact->firstname = (
string) ($args[
'firstname'] ??
'');
656 $contact->lastname = (
string) $args[
'lastname'];
657 $contact->email = isset($args[
'email']) ? (
string) $args[
'email'] :
'';
658 $contact->phone_pro = isset($args[
'phone']) ? (
string) $args[
'phone'] :
'';
659 $contact->poste = isset($args[
'role']) ? (
string) $args[
'role'] :
'';
662 if ($contact->create($this->user) > 0) {
664 "status" =>
"success",
665 "message" =>
"Contact created successfully.",
666 "id" => (int) $contact->id,
667 "url" => DOL_URL_ROOT .
"/contact/card.php?id=" . $contact->id
671 return [
"error" =>
"Failed to create contact: " . (
string) $contact->error];
Class to manage third parties objects (customers, suppliers, prospects...)
getCountry($searchkey, $withcode='', $dbtouse=null, $outputlangs=null, $entconv=1, $searchlabel='')
Return country label, code or id from an id, code or label.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
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
$conf db user
Active Directory does not allow anonymous connections.