dolibarr 24.0.1
contacts.tpl.php
1<?php
2/* Copyright (C) 2012 Regis Houssin <regis.houssin@inodbox.com>
3 * Copyright (C) 2013-2015 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2015-2016 Charlie BENKE <charlie@patas-monkey.com>
5 * Copyright (C) 2021-2026 Frédéric France <frederic.france@free.fr>
6 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
7 * Copyright (C) 2024 Solution Libre SAS <contact@solution-libre.fr>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 *
22 * This template needs:
23 * $object
24 * $withproject (if we are on task contact)
25 *
26 * $preselectedtypeofcontact may be defined or not
27 */
41'
42@phan-var-force ?CommonObject $object
43@phan-var-force ?CommonObject $objectsrc
44@phan-var-force ?string $permission
45';
46
47// Protection to avoid direct call of template
48if (empty($object) || !is_object($object)) {
49 print "Error, template page can't be called as URL";
50 exit(1);
51}
52
53
54if (empty($preselectedtypeofcontact)) {
55 $preselectedtypeofcontact = 0;
56}
57
58require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
59require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
60
61$module = $object->element;
62
63// Special cases
64if (isset($permissiontoadd) && !isset($permission)) {
65 $permission = $permissiontoadd;
66}
67// TODO Remove this section. We already got $permissiontoadd.
68if ($module == 'propal') {
69 $permission = $user->hasRight('propal', 'creer');
70} elseif ($module == 'fichinter') {
71 $permission = $user->hasRight('ficheinter', 'creer');
72} elseif ($module == 'order_supplier') {
73 if (!getDolGlobalString('MAIN_USE_NEW_SUPPLIERMOD')) {
74 $permission = $user->hasRight('fournisseur', 'commande', 'creer');
75 } else {
76 $permission = $user->hasRight('supplier_order', 'creer');
77 }
78} elseif ($module == 'invoice_supplier') {
79 if (!getDolGlobalString('MAIN_USE_NEW_SUPPLIERMOD')) {
80 $permission = $user->hasRight('fournisseur', 'facture', 'creer');
81 } else {
82 $permission = $user->hasRight('supplier_invoice', 'creer');
83 }
84} elseif ($module == 'project') {
85 $permission = $user->hasRight('projet', 'creer');
86} elseif ($module == 'action') {
87 $permission = $user->hasRight('agenda', 'myactions', 'create');
88} elseif ($module == 'shipping') {
89 $permission = $user->hasRight('expedition', 'creer');
90} elseif ($module == 'reception') {
91 $permission = $user->hasRight('reception', 'creer');
92} elseif ($module == 'project_task') {
93 $permission = $user->hasRight('projet', 'creer');
94} elseif (!isset($permission) && $user->hasRight($module, 'creer')) {
95 $permission = $user->hasRight($module, 'creer');
96} elseif (!isset($permission) && $user->hasRight($module, 'write')) {
97 $permission = $user->hasRight($module, 'write');
98}
99
100$formcompany = new FormCompany($db);
101$companystatic = new Societe($db);
102$contactstatic = new Contact($db);
103$userstatic = new User($db);
104
105?>
106
107<!-- BEGIN PHP TEMPLATE CORE/TPL/CONTACTS.TPL.PHP -->
108<?php
109if ($permission) {
110 print '<div class="underbanner clearboth"></div>'."\n";
111
112 print '<div class="div-table-responsive-no-min">'."\n";
113 print '<div class="tagtable tableforcontact centpercent noborder nobordertop allwidth">'."\n"; ?>
114 <form class="tagtr liste_titre">
115 <div class="tagtd liste_titre"><?php echo img_object('', 'company', 'class="optiongrey paddingright"').$langs->trans("ThirdParty"); ?></div>
116 <div class="tagtd liste_titre"><?php echo img_picto($langs->trans("Users"), 'user', 'class="optiongrey paddingright"').$langs->trans("Users").' | '.img_picto($langs->trans("Contacts"), 'contact', 'class="optiongrey paddingright"').$langs->trans("Contacts"); ?></div>
117 <div class="tagtd liste_titre"><?php echo $langs->trans("ContactType"); ?></div>
118 <div class="tagtd liste_titre">&nbsp;</div>
119 <div class="tagtd liste_titre">&nbsp;</div>
120 </form>
121
122 <?php
123
124 if (empty($hideaddcontactforuser)) {
125 ?>
126 <form class="tagtr impair nohover" action="<?php echo $_SERVER["PHP_SELF"].'?id='.$object->id; ?>" method="POST">
127 <input type="hidden" name="token" value="<?php echo newToken(); ?>" />
128 <input type="hidden" name="id" value="<?php echo $object->id; ?>" />
129 <input type="hidden" name="action" value="addcontact" />
130 <input type="hidden" name="source" value="internal" />
131 <?php if (!empty($withproject)) {
132 print '<input type="hidden" name="withproject" value="'.$withproject.'">';
133 } ?>
134
135 <div class="tagtd"><span class="paddingleft"><?php echo getDolGlobalString('MAIN_INFO_SOCIETE_NOM'); ?></span></div>
136 <!-- <div class="nowrap tagtd"><?php echo img_object('', 'user').' '.$langs->trans("Users"); ?></div> -->
137 <div class="tagtd maxwidthonsmartphone">
138 <?php echo img_object('', 'user', 'class="pictofixedwidth"').$form->select_dolusers($user->id, 'userid', 1, (!empty($userAlreadySelected) ? $userAlreadySelected : null), 0, '', '', '0', 56, 0, '', 0, '', 'minwidth100imp widthcentpercentminusxx maxwidth400 userselectcontact');
139 if (empty($hideaddcontactforgroups) && $module == 'project') {
140 print '<span class="opacitymedium"> '.$langs->trans("or").' </span>';
141 echo img_object('', 'group', 'class="pictofixedwidth"').$form->select_dolgroups(0, 'groupid', 1, '', 0, '', array(), '0', false, 'minwidth100imp widthcentpercentminusxx maxwidth400 groupselectcontact');
142 }
143 ?>
144 <script>
145 jQuery(document).ready(function(){
146 $(".userselectcontact").on("change", function(){
147 if ($(this).val() != -1) {
148 $(".groupselectcontact").val(-1).change();
149 }
150 });
151 $(".groupselectcontact").on("change", function(){
152 if ($(this).val() != -1) {
153 $(".userselectcontact").val(-1).change();
154 }
155 });
156 });
157 </script>
158 </div>
159 <div class="tagtd maxwidthonsmartphone">
160 <?php
161 $tmpobject = $object;
162 if (((!getDolGlobalInt('SHIPPING_USE_ITS_OWN_CONTACTS') && $object->element == 'shipping') || $object->element == 'reception') && is_object($objectsrc)) {
163 $tmpobject = $objectsrc;
164 }
165 $formcompany->selectTypeContact($tmpobject, '', 'type', 'internal', 'position', 0, 'minwidth150imp widthcentpercentminusx maxwidth200'); ?></div>
166 <div class="tagtd">&nbsp;</div>
167 <div class="tagtd center"><input type="submit" class="button small" value="<?php echo $langs->trans("Add"); ?>"></div>
168 </form>
169 <?php
170 }
171
172 if (empty($hideaddcontactforthirdparty)) {
173 ?>
174
175 <form class="tagtr pair nohover" action="<?php echo $_SERVER["PHP_SELF"].'?id='.$object->id; ?>" method="POST">
176 <input type="hidden" name="token" value="<?php echo newToken(); ?>" />
177 <input type="hidden" name="id" value="<?php echo $object->id; ?>" />
178 <input type="hidden" name="action" value="addcontact" />
179 <input type="hidden" name="source" value="external" />
180 <input type="hidden" name="page_y" value="" />
181 <?php if (!empty($withproject)) {
182 print '<input type="hidden" name="withproject" value="'.$withproject.'">';
183 } ?>
184
185 <div class="tagtd nowrap noborderbottom">
186 <?php
187 $selectedCompany = GETPOSTISSET("newcompany") ? GETPOSTINT("newcompany") : (empty($object->socid) ? 0 : $object->socid);
188 $selectedCompany = $formcompany->selectCompaniesForNewContact($object, 'id', $selectedCompany, 'newcompany', array(), 0, '', 'minwidth300imp maxwidth400 widthcentpercentminusx'); // This also print the select component?>
189 </div>
190 <div class="tagtd noborderbottom minwidth500imp">
191 <?php
192 print img_object('', 'contact', 'class="pictofixedwidth"');
193 //print $form->selectcontacts(($selectedCompany > 0 ? $selectedCompany : -1), '', 'contactid', 3, '', '', 1, 'minwidth100imp widthcentpercentminusxx maxwidth400');
194 print $form->select_contact(($selectedCompany > 0 ? $selectedCompany : -1), '', 'contactid', 3, '', '', 1, 'minwidth100imp maxwidth400 widthcentpercentminusx', true);
195
196 $nbofcontacts = $form->num;
197
198 $newcardbutton = '';
199 if (!empty($object->socid) && $object->socid > 1 && $user->hasRight('societe', 'creer')) {
200 $newcardbutton .= '<a href="'.DOL_URL_ROOT.'/contact/card.php?socid='.$selectedCompany.'&action=create&backtopage='.urlencode($_SERVER["PHP_SELF"].'?id='.$object->id).'" title="'.$langs->trans('NewContact').'"><span class="fa fa-plus-circle valignmiddle paddingleft"></span></a>';
201 }
202 print $newcardbutton; ?>
203 </div>
204 <div class="tagtd noborderbottom">
205 <?php
206 $tmpobject = $object;
207 if (((!getDolGlobalInt('SHIPPING_USE_ITS_OWN_CONTACTS') && $object->element == 'shipping') || $object->element == 'reception') && is_object($objectsrc)) {
208 '@phan-var-force Commande|Facture $objectsrc';
209 $tmpobject = $objectsrc;
210 }
211 $formcompany->selectTypeContact($tmpobject, $preselectedtypeofcontact, 'typecontact', 'external', 'position', 0, 'minwidth150imp widthcentpercentminusx maxwidth200'); ?>
212 </div>
213 <div class="tagtd noborderbottom">&nbsp;</div>
214 <div class="tagtd center noborderbottom">
215 <input type="submit" id="add-customer-contact" class="button small" value="<?php echo $langs->trans("Add"); ?>"<?php if (!$nbofcontacts) {
216 echo ' disabled';
217 } ?>>
218 </div>
219 </form>
220
221 <?php
222 }
223
224 print "</div>";
225 print "</div>";
226
227 print '<br>';
228}
229
230
231// Prepare list
232
233// TODO: replace this with 1 single direct SQL (for both internal and external string to use $db->sort($sortfield, $sortorder)
234$list = array();
235foreach (array('internal', 'external') as $source) {
236 if (((!getDolGlobalInt('SHIPPING_USE_ITS_OWN_CONTACTS') && $object->element == 'shipping') || $object->element == 'reception') && is_object($objectsrc)) {
237 '@phan-var-force Commande|Facture $objectsrc';
238 $contactlist = $objectsrc->liste_contact(-1, $source);
239 } else {
240 $contactlist = $object->liste_contact(-1, $source);
241 }
242
243 foreach ($contactlist as $contact) {
244 $entry = new stdClass();
245 $entry->id = $contact['rowid'];
246 $entry->type_id = $contact['fk_c_type_contact'];
247 $entry->type = $contact['libelle'];
248 $entry->nature = "";
249 $entry->nature_html = "";
250 $entry->thirdparty_id = 0;
251 $entry->thirdparty_html = "";
252 $entry->thirdparty_name = "";
253 $entry->contact_html = "";
254 $entry->contact_name = "";
255 $entry->status = 0;
256 $entry->status_html = "";
257
258 if ($contact['source'] == 'internal') {
259 $entry->nature = 'user';
260 $entry->nature_html = $langs->trans("User");
261 } elseif ($contact['source'] == 'external') {
262 $entry->nature = 'thirdparty';
263 $entry->nature_html = $langs->trans("ThirdPartyContact");
264 }
265
266 if ($contact['socid'] > 0) {
267 $companystatic->fetch($contact['socid']);
268 $entry->thirdparty_id = $companystatic->id;
269 $entry->thirdparty_html = $companystatic->getNomUrl(1);
270 $entry->thirdparty_name = strtolower($companystatic->getFullName($langs));
271 } elseif ($contact['socid'] < 0) {
272 $entry->thirdparty_html = getDolGlobalString('MAIN_INFO_SOCIETE_NOM');
273 $entry->thirdparty_name = strtolower(getDolGlobalString('MAIN_INFO_SOCIETE_NOM'));
274 }
275
276 if ($contact['source'] == 'internal') {
277 $userstatic->fetch($contact['id']);
278 $entry->contact_id = $userstatic->id;
279 $entry->contact_html = $userstatic->getNomUrl(-1, '', 0, 0, 0, 0, '', 'valignmiddle');
280 $entry->contact_name = strtolower($userstatic->getFullName($langs));
281 $entry->contact_warning = 0;
282 } elseif ($contact['source'] == 'external') {
283 $contactstatic->fetch($contact['id']);
284 $entry->contact_id = $contactstatic->id;
285 $entry->contact_html = $contactstatic->getNomUrl(1, '', 0, '', 0, 0);
286 $entry->contact_name = strtolower($contactstatic->getFullName($langs));
287 $entry->contact_warning = $contactstatic->user_id; // Show warning to recommend to assign user_id as contact instead.
288 }
289
290 if ($contact['source'] == 'internal') {
291 $entry->status = $contact['statuscontact'] ? $contact['status'] : 0; // statuscontact=status of contact, status=status of link
292 $entry->status_html = $userstatic->LibStatut($entry->status == 4 ? 1 : 0, 3);
293 $entry->status_html = '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.((int) $object->id).'&action=swapstatut&token='.newToken().'&ligne='.((int) $entry->id).(!empty($withproject) ? '&withproject=1' : '').'">'.$entry->status_html.'</a>';
294 } elseif ($contact['source'] == 'external') {
295 $entry->status = $contact['statuscontact'] ? $contact['status'] : 0; // statuscontact=status of contact, status=status of link
296 $entry->status_html = $contactstatic->LibStatut($entry->status == 4 ? 1 : 0, 3);
297 $entry->status_html = '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.((int) $object->id).'&action=swapstatut&token='.newToken().'&ligne='.((int) $entry->id).(!empty($withproject) ? '&withproject=1' : '').'">'.$entry->status_html.'</a>';
298 }
299
300 $list[] = $entry;
301 }
302}
303
304
305$sortfield = GETPOST("sortfield", "aZ09comma");
306$sortorder = GETPOST("sortorder", 'aZ09comma');
307
308if (!$sortfield) {
309 $sortfield = "nature";
310}
311if (!$sortorder) {
312 $sortorder = "asc";
313}
314
315// Re-sort list
316$list = dol_sort_array($list, $sortfield, $sortorder, 1, 0, 1);
317
318$arrayfields = array(
319 'rowid' => array('label' => $langs->trans("Id"), 'checked' => 1),
320 'nature' => array('label' => $langs->trans("NatureOfContact"), 'checked' => 1),
321 'thirdparty' => array('label' => $langs->trans("ThirdParty"), 'checked' => 1),
322 'contact' => array('label' => $langs->trans("Users").' | '.$langs->trans("Contacts"), 'checked' => 1),
323 'type' => array('label' => $langs->trans("ContactType"), 'checked' => 1),
324 'status' => array('label' => $langs->trans("Status"), 'checked' => 1),
325 'link' => array('label' => $langs->trans("Link"), 'checked' => 1),
326);
327
328$param = 'id='.$object->id.'&mainmenu=home';
329
330
331// Show list of contact links
332
333print '<form method="POST" id="searchFormList" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'">';
334print '<input type="hidden" name="token" value="'.newToken().'">';
335print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
336print '<input type="hidden" name="action" value="list">';
337print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
338print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
339
340print '<div class="div-table-responsive-no-min">'."\n";
341print '<table class="tagtable nobottomiftotal liste noborder">';
342
343print '<tr class="liste_titre">';
344print_liste_field_titre($arrayfields['thirdparty']['label'], $_SERVER["PHP_SELF"], "thirdparty_name", "", $param, "", $sortfield, $sortorder);
345print_liste_field_titre($arrayfields['contact']['label'], $_SERVER["PHP_SELF"], "contact_name", "", $param, "", $sortfield, $sortorder);
346print_liste_field_titre($arrayfields['nature']['label'], $_SERVER["PHP_SELF"], "nature", "", $param, "", $sortfield, $sortorder);
347print_liste_field_titre($arrayfields['type']['label'], $_SERVER["PHP_SELF"], "type", "", $param, "", $sortfield, $sortorder);
348print_liste_field_titre($arrayfields['status']['label'], $_SERVER["PHP_SELF"], "statut", "", $param, "", $sortfield, $sortorder, 'center ');
349if ($permission) {
350 print_liste_field_titre('', $_SERVER["PHP_SELF"], "", "", "", "", $sortfield, $sortorder, 'center maxwidthsearch ');
351}
352print "</tr>";
353
354foreach ($list as $entry) {
355 print '<tr class="oddeven" data-rowid="' . $entry->id . '">';
356
357 print '<td class="tdoverflowmax200" data-thirdparty_id="' . ((int) $entry->thirdparty_id) . '" data-thirdparty_name="' . dol_escape_htmltag($entry->thirdparty_name) . '">'.$entry->thirdparty_html.'</td>';
358 print '<td class="tdoverflowmax200" data-contact_id="' . ((int) $entry->contact_id) . '">'.$entry->contact_html.'</td>';
359 print '<td class="nowrap" data-nature="' . dol_escape_htmltag($entry->nature) . '"><span class="opacitymedium">'.dol_escape_htmltag($entry->nature_html).'</span>';
360 if ($entry->contact_warning > 0) {
361 $tmpuser = new User($db);
362 $tmpuser->fetch($entry->contact_warning);
363 print ($tmpuser->id > 0 ? img_picto($langs->trans("ThisContactHasAUser", $tmpuser->getFullName($langs), $entry->contact_name), 'info') : '');
364 }
365 print '</td>';
366 print '<td class="tdoverflowmax200" data-type_id="' . ((int) $entry->type_id) . '" data-type="' . dol_escape_htmltag($entry->type) . '">'.dol_escape_htmltag($langs->trans($entry->type)).'</td>';
367 print '<td class="tdoverflowmax200 center" data-status_id="' . ((int) $entry->status) . '">'.$entry->status_html.'</td>';
368
369 if ($permission) {
370 $href = $_SERVER["PHP_SELF"];
371 $href .= '?id='.((int) $object->id);
372 $href .= '&action=deletecontact&token='.newToken();
373 $href .= '&lineid='.((int) $entry->id);
374
375 print '<td class="center">';
376 print '<a href="'.$href.'">';
377 print img_picto($langs->trans("Unlink"), "unlink");
378 print "</a>";
379 print "</td>";
380 }
381
382 print "</tr>";
383}
384if (empty($list)) {
385 $colspan = 5 + ($permission ? 1 : 0);
386 print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">';
387 if (is_object($object) && !empty($object->thirdparty)) {
388 print $form->textwithpicto($langs->trans("NoSpecificContactAddress"), $langs->trans("NoSpecificContactAddressBis"));
389 } else {
390 print $langs->trans("NoSpecificContactAddress");
391 }
392 print '</span>';
393 print '</td></tr>';
394}
395print "</table>";
396print '</div>';
397
398print "</form>";
399
400print "<!-- TEMPLATE CONTACTS HOOK BEGIN HERE -->\n";
401if (is_object($hookmanager)) {
402 $hookmanager->initHooks(array('contacttpl'));
403 $parameters = array();
404 // @phan-suppress-next-line PhanTypeMismatchArgumentNullable
405 $reshook = $hookmanager->executeHooks('formContactTpl', $parameters, $object, $action);
406}
407print "<!-- END PHP TEMPLATE CONTACTS -->\n";
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
Class to manage contact/addresses.
Class to build HTML component for third parties management Only common components are here.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
print_liste_field_titre($name, $file="", $field="", $begin="", $param="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_sort_array(&$array, $index, $order='asc', $natsort=0, $case_sensitive=0, $keepindex=0)
Advanced sort array by the value of a given key, which produces ascending (default) or descending out...
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
if(preg_match('/(crypted|dolcrypt):/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',...
Definition repair.php:130
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:133