74 public $errors = array();
85 public $cache_types_paiements = array();
87 public $cache_conditions_paiements = array();
89 public $cache_transport_mode = array();
91 public $cache_availability = array();
93 public $cache_demand_reason = array();
95 public $cache_types_fees = array();
97 public $cache_vatrates = array();
99 public $cache_invoice_subtype = array();
101 public $cache_rule_for_lines_dates = array();
106 private $phoneInputSharedJsLoaded =
false;
131 'y' => $langs->trans(
'Years'),
132 'm' => $langs->trans(
'Month'),
133 'w' => $langs->trans(
'Weeks'),
134 'd' => $langs->trans(
'Days'),
135 'h' => $langs->trans(
'Hours'),
136 'i' => $langs->trans(
'Minutes'),
137 's' => $langs->trans(
'Seconds'),
141 "y" => $langs->trans(
"Year"),
142 "m" => $langs->trans(
"Month"),
143 "w" => $langs->trans(
"Week"),
144 "d" => $langs->trans(
"Day"),
145 "h" => $langs->trans(
"Hour"),
146 "i" => $langs->trans(
"Minute"),
147 's' => $langs->trans(
'Second'),
151 return array_reverse($arrayoftypes);
153 return $arrayoftypes;
173 public function editfieldkey($text, $htmlname, $preselected,
$object, $perm, $typeofdata =
'string', $moreparam =
'', $fieldrequired = 0, $notabletag = 0, $paramid =
'id', $help =
'')
180 if (
getDolGlobalString(
'MAIN_USE_EDIT_IN_PLACE') && !preg_match(
'/^select;/', $typeofdata)) {
182 $tmp = explode(
':', $typeofdata);
183 $ret .=
'<div class="editkey_' . $tmp[0] . (!empty($tmp[1]) ?
' ' . $tmp[1] :
'') .
'" id="' . $htmlname .
'">';
184 if ($fieldrequired) {
185 $ret .=
'<span class="fieldrequired">';
190 $ret .= $langs->trans($text);
192 if ($fieldrequired) {
195 $ret .=
'</div>' .
"\n";
197 if ($fieldrequired) {
198 $ret .=
'<span class="fieldrequired">';
203 $ret .= $langs->trans($text);
205 if ($fieldrequired) {
210 if (empty($notabletag) && $perm) {
211 $ret .=
'<table class="nobordernopadding centpercent"><tr><td class="nowrap">';
213 if ($fieldrequired) {
214 $ret .=
'<span class="fieldrequired">';
219 $ret .= $langs->trans($text);
221 if ($fieldrequired) {
224 if (!empty($notabletag)) {
227 if (empty($notabletag) && $perm) {
230 if (empty($notabletag) && $perm) {
231 $ret .=
'<td class="right">';
233 if ($htmlname &&
GETPOST(
'action',
'aZ09') !=
'edit' . $htmlname && $perm && is_object(
$object)) {
234 $ret .=
'<a class="editfielda reposition" href="' .
dolBuildUrl($_SERVER[
"PHP_SELF"], [
'action' =>
'edit' . $htmlname, $paramid =>
$object->id],
true) . $moreparam .
'">';
235 $ret .= img_edit($langs->trans(
'Edit'), ($notabletag ? 0 : 1));
238 if (!empty($notabletag) && $notabletag == 1) {
245 if (!empty($notabletag) && $notabletag == 3) {
248 if (empty($notabletag) && $perm) {
251 if (empty($notabletag) && $perm) {
252 $ret .=
'</tr></table>';
282 public function editfieldval($text, $htmlname, $value,
$object, $perm, $typeofdata =
'string', $editvalue =
'', $extObject =
null, $custommsg =
null, $moreparam =
'', $notabletag = 1, $formatfunc =
'', $paramid =
'id', $gm =
'auto', $moreoptions = array(), $editaction =
'')
284 global
$conf, $langs;
289 if (empty($typeofdata)) {
290 return 'ErrorBadParameter typeofdata is empty';
293 if ($typeofdata ==
'datetime') {
294 $typeofdata =
'dayhour';
296 if ($typeofdata ==
'date') {
300 if (preg_match(
'/^(\w+)\((\d+)\)$/', $typeofdata, $reg)) {
301 if ($reg[1] ==
'varchar') {
302 $typeofdata =
'string';
303 } elseif ($reg[1] ==
'int') {
304 $typeofdata =
'numeric';
306 return 'ErrorBadParameter ' . $typeofdata;
311 if (
getDolGlobalString(
'MAIN_USE_EDIT_IN_PLACE') && !preg_match(
'/^select;|day|datepicker|dayhour|datehourpicker/', $typeofdata)) {
312 $ret .= $this->
editInPlace(
$object, $value, $htmlname, ($perm ? 1 : 0), $typeofdata, $editvalue, $extObject, $custommsg);
314 if ($editaction ==
'') {
315 $editaction =
GETPOST(
'action',
'aZ09');
317 $editmode = ($editaction ==
'edit' . $htmlname);
319 $ret .=
"<!-- formeditfieldval -->\n";
320 $ret .=
'<form method="post" action="' . $_SERVER[
"PHP_SELF"] . ($moreparam ?
'?' . $moreparam :
'') .
'">';
321 $ret .=
'<input type="hidden" name="action" value="set' . $htmlname .
'">';
322 $ret .=
'<input type="hidden" name="token" value="' .
newToken() .
'">';
323 $ret .=
'<input type="hidden" name="' . $paramid .
'" value="' .
$object->id .
'">';
324 if (empty($notabletag)) {
325 $ret .=
'<table class="nobordernopadding centpercent">';
327 if (empty($notabletag)) {
330 if (preg_match(
'/^(string|safehtmlstring|email|phone|url)/', $typeofdata)) {
331 $tmp = explode(
':', $typeofdata);
332 $ret .=
'<input type="text" id="' . $htmlname .
'" name="' . $htmlname .
'" value="' . ($editvalue ? $editvalue : $value) .
'"' . (empty($tmp[1]) ?
'' :
' size="' . $tmp[1] .
'"') .
' autofocus spellcheck="false">';
333 } elseif (preg_match(
'/^(integer)/', $typeofdata)) {
334 $tmp = explode(
':', $typeofdata);
335 $valuetoshow =
price2num($editvalue ? $editvalue : $value, 0);
336 $ret .=
'<input type="text" id="' . $htmlname .
'" name="' . $htmlname .
'" value="' . $valuetoshow .
'"' . (empty($tmp[1]) ?
'' :
' size="' . $tmp[1] .
'"') .
' autofocus>';
337 } elseif (preg_match(
'/^(numeric|amount)/', $typeofdata)) {
338 $tmp = explode(
':', $typeofdata);
339 $valuetoshow =
price2num($editvalue ? $editvalue : $value);
340 $ret .=
'<input type="text" id="' . $htmlname .
'" name="' . $htmlname .
'" value="' . ($valuetoshow !=
'' ?
price($valuetoshow) :
'') .
'"' . (empty($tmp[1]) ?
'' :
' size="' . $tmp[1] .
'"') .
' autofocus>';
341 } elseif (preg_match(
'/^(checkbox)/', $typeofdata)) {
342 $tmp = explode(
':', $typeofdata);
343 $ret .=
'<input type="checkbox" id="' . $htmlname .
'" name="' . $htmlname .
'" value="' . ($value ? $value :
'on') .
'"' . ($value ?
' checked' :
'') . (empty($tmp[1]) ?
'' : $tmp[1]) .
'/>';
344 } elseif (preg_match(
'/^text/', $typeofdata) || preg_match(
'/^note/', $typeofdata)) {
345 $tmp = explode(
':', $typeofdata);
346 $cols = (empty($tmp[2]) ?
'' : $tmp[2]);
348 if (preg_match(
'/%/', $cols)) {
349 $morealt =
' style="width: ' . $cols .
'"';
352 $valuetoshow = ($editvalue ? $editvalue : $value);
353 $ret .=
'<textarea id="' . $htmlname .
'" name="' . $htmlname .
'" wrap="soft" rows="' . (empty($tmp[1]) ?
'20' : $tmp[1]) .
'"' . ($cols ?
' cols="' . $cols .
'"' :
'class="quatrevingtpercent"') . $morealt .
'" autofocus>';
356 $valuetoshow = str_replace(
'&',
'&', $valuetoshow);
358 $ret .=
'</textarea><div class="clearboth"></div>';
359 } elseif ($typeofdata ==
'day' || $typeofdata ==
'datepicker') {
360 $addnowlink = empty($moreoptions[
'addnowlink']) ? 0 : $moreoptions[
'addnowlink'];
361 $adddateof = empty($moreoptions[
'adddateof']) ?
'' : $moreoptions[
'adddateof'];
362 $labeladddateof = empty($moreoptions[
'labeladddateof']) ?
'' : $moreoptions[
'labeladddateof'];
363 $ret .= $this->
selectDate($value, $htmlname, 0, 0, 1,
'form' . $htmlname, 1, $addnowlink, 0,
'',
'', $adddateof,
'', 1, $labeladddateof,
'', $gm);
364 } elseif ($typeofdata ==
'dayhour' || $typeofdata ==
'datehourpicker') {
365 $addnowlink = empty($moreoptions[
'addnowlink']) ? 0 : $moreoptions[
'addnowlink'];
366 $adddateof = empty($moreoptions[
'adddateof']) ?
'' : $moreoptions[
'adddateof'];
367 $labeladddateof = empty($moreoptions[
'labeladddateof']) ?
'' : $moreoptions[
'labeladddateof'];
368 $ret .= $this->
selectDate($value, $htmlname, 1, 1, 1,
'form' . $htmlname, 1, $addnowlink, 0,
'',
'', $adddateof,
'', 1, $labeladddateof,
'', $gm);
369 } elseif (preg_match(
'/^select;/', $typeofdata)) {
370 $arraydata = explode(
',', preg_replace(
'/^select;/',
'', $typeofdata));
371 $arraylist = array();
372 foreach ($arraydata as $val) {
373 $tmp = explode(
':', $val);
374 $tmpkey = str_replace(
'|',
':', $tmp[0]);
375 $arraylist[$tmpkey] = $tmp[1];
377 $ret .= $this->
selectarray($htmlname, $arraylist, $value);
378 } elseif (preg_match(
'/^link/', $typeofdata)) {
380 } elseif (preg_match(
'/^ckeditor/', $typeofdata)) {
381 $tmp = explode(
':', $typeofdata);
382 require_once DOL_DOCUMENT_ROOT .
'/core/class/doleditor.class.php';
383 $doleditor =
new DolEditor($htmlname, ($editvalue ? $editvalue : $value), (empty($tmp[2]) ?
'' : $tmp[2]), (empty($tmp[3]) ? 100 : (int) $tmp[3]), (empty($tmp[1]) ?
'dolibarr_notes' : $tmp[1]),
'In', (empty($tmp[5]) ? false : (bool) $tmp[5]), (isset($tmp[8]) ? ($tmp[8] ? true :
false) :
true),
true, (empty($tmp[6]) ? 20 : (int) $tmp[6]), (empty($tmp[7]) ?
'100' : $tmp[7]));
384 $ret .= $doleditor->Create(1);
385 } elseif ($typeofdata ==
'asis') {
386 $ret .= ($editvalue ? $editvalue : $value);
388 if (empty($notabletag)) {
393 if (empty($notabletag)) {
397 $ret .=
'<input type="submit" class="smallpaddingimp nomargingtop nomarginbottom button' . (empty($notabletag) ?
'' :
' ') .
'" name="modify" value="' . $langs->trans(
"Save") .
'">';
398 if (preg_match(
'/ckeditor|textarea/', $typeofdata) && empty($notabletag)) {
399 $ret .=
'<br>' .
"\n";
401 $ret .=
'<input type="submit" class="smallpaddingimp nomargingtop nomarginbottom button button-cancel' . (empty($notabletag) ?
'' :
' ') .
'" name="cancel" value="' . $langs->trans(
"Cancel") .
'">';
402 if (empty($notabletag)) {
406 if (empty($notabletag)) {
407 $ret .=
'</tr></table>' .
"\n";
409 $ret .=
'</form>' .
"\n";
411 if (preg_match(
'/^email/', $typeofdata)) {
413 } elseif (preg_match(
'/^phone/', $typeofdata)) {
415 } elseif (preg_match(
'/^url/', $typeofdata)) {
417 } elseif (preg_match(
'/^(amount|numeric)/', $typeofdata)) {
418 $ret .= ($value !=
'' ?
price($value, 0, $langs, 0, -1, -1,
$conf->currency) :
'');
419 } elseif (preg_match(
'/^checkbox/', $typeofdata)) {
420 $tmp = explode(
':', $typeofdata);
421 $ret .=
'<input type="checkbox" disabled id="' . $htmlname .
'" name="' . $htmlname .
'" value="' . $value .
'"' . ($value ?
' checked' :
'') . ($tmp[1] ? $tmp[1] :
'') .
'/>';
422 } elseif (preg_match(
'/^text/', $typeofdata) || preg_match(
'/^note/', $typeofdata)) {
424 } elseif (preg_match(
'/^(safehtmlstring|restricthtml)/', $typeofdata)) {
426 } elseif ($typeofdata ==
'day' || $typeofdata ==
'datepicker') {
427 $ret .=
'<span class="valuedate">' .
dol_print_date($value,
'day', $gm) .
'</span>';
428 } elseif ($typeofdata ==
'dayhour' || $typeofdata ==
'datehourpicker') {
429 $ret .=
'<span class="valuedate">' .
dol_print_date($value,
'dayhour', $gm) .
'</span>';
430 } elseif (preg_match(
'/^select;/', $typeofdata)) {
431 $arraydata = explode(
',', preg_replace(
'/^select;/',
'', $typeofdata));
432 $arraylist = array();
433 foreach ($arraydata as $val) {
434 $tmp = explode(
':', $val);
435 $arraylist[$tmp[0]] = $tmp[1];
437 $ret .= $arraylist[$value];
438 if ($htmlname ==
'fk_product_type') {
440 $ret = img_picto($langs->trans(
"Product"),
'product',
'class="paddingleftonly paddingrightonly colorgrey"') . $ret;
442 $ret = img_picto($langs->trans(
"Service"),
'service',
'class="paddingleftonly paddingrightonly colorgrey"') . $ret;
445 } elseif (preg_match(
'/^ckeditor/', $typeofdata)) {
448 $firstline = preg_replace(
'/<br>.*/',
'', $tmpcontent);
449 $firstline = preg_replace(
'/[\n\r].*/',
'', $firstline);
450 $tmpcontent = $firstline . ((strlen($firstline) != strlen($tmpcontent)) ?
'...' :
'');
456 if (empty($moreoptions[
'valuealreadyhtmlescaped'])) {
464 if ($formatfunc && method_exists(
$object, $formatfunc)) {
465 $ret =
$object->$formatfunc($ret);
485 global
$conf, $langs, $extralanguages;
490 $arrayoflangcode = array();
495 if (is_array($arrayoflangcode) && count($arrayoflangcode)) {
496 if (!is_object($extralanguages)) {
497 include_once DOL_DOCUMENT_ROOT .
'/core/class/extralanguages.class.php';
500 $extralanguages->fetch_name_extralanguages(
'societe');
505 if (empty($extralanguages->attributes[
$object->element]) || !is_array($extralanguages->attributes[
$object->element]) || empty($extralanguages->attributes[
$object->element][$fieldname])) {
509 $result .=
'<!-- Widget for translation -->' .
"\n";
510 $result .=
'<div class="inline-block paddingleft image-' .
$object->element .
'-' . $fieldname .
'">';
511 $s = img_picto($langs->trans(
"ShowOtherLanguages"),
'language',
'', 0, 0, 0,
'',
'fa-15 editfieldlang');
515 $result .=
'<div class="inline-block hidden field-' .
$object->element .
'-' . $fieldname .
'">';
517 $resultforextrlang =
'';
518 foreach ($arrayoflangcode as $langcode) {
519 $valuetoshow =
GETPOSTISSET(
'field-' .
$object->element .
"-" . $fieldname .
"-" . $langcode) ?
GETPOST(
'field-' .
$object->element .
'-' . $fieldname .
"-" . $langcode, $check) :
'';
520 if (empty($valuetoshow)) {
521 $object->fetchValuesForExtraLanguages();
523 $valuetoshow =
$object->array_languages[$fieldname][$langcode];
527 $resultforextrlang .= $s;
530 if ($typeofdata ==
'textarea') {
531 $resultforextrlang .=
'<textarea name="field-' .
$object->element .
"-" . $fieldname .
"-" . $langcode .
'" id="' . $fieldname .
"-" . $langcode .
'" class="' . $morecss .
'" rows="' . ROWS_2 .
'" wrap="soft">';
532 $resultforextrlang .= $valuetoshow;
533 $resultforextrlang .=
'</textarea>';
535 $resultforextrlang .=
'<input type="text" class="inputfieldforlang ' . ($morecss ?
' ' . $morecss :
'') .
'" name="field-' .
$object->element .
'-' . $fieldname .
'-' . $langcode .
'" value="' . $valuetoshow .
'">';
538 $result .= $resultforextrlang;
541 $result .=
'<script nonce="' .
getNonce() .
'">$(".image-' .
$object->element .
'-' . $fieldname .
'").click(function() { console.log("Toggle lang widget"); jQuery(".field-' .
$object->element .
'-' . $fieldname .
'").toggle(); });</script>';
560 protected function editInPlace(
$object, $value, $htmlname, $condition, $inputType =
'textarea', $editvalue =
null, $extObject =
null, $custommsg =
null)
565 if (preg_match(
'/^text/', $inputType)) {
567 } elseif (preg_match(
'/^numeric/', $inputType)) {
568 $value =
price($value);
569 } elseif ($inputType ==
'day' || $inputType ==
'datepicker') {
575 $table_element =
false;
579 $ext_element =
false;
580 $button_only =
false;
587 $table_element =
$object->table_element;
591 if (is_object($extObject)) {
592 $ext_element = $extObject->element;
595 if (preg_match(
'/^(string|email|numeric)/', $inputType)) {
596 $tmp = explode(
':', $inputType);
597 $inputType = $tmp[0];
598 if (!empty($tmp[1])) {
599 $inputOption = $tmp[1];
601 if (!empty($tmp[2])) {
602 $savemethod = $tmp[2];
604 $out .=
'<input id="width_' . $htmlname .
'" value="' . $inputOption .
'" type="hidden"/>' .
"\n";
605 } elseif ((preg_match(
'/^day$/', $inputType)) || (preg_match(
'/^datepicker/', $inputType)) || (preg_match(
'/^datehourpicker/', $inputType))) {
606 $tmp = explode(
':', $inputType);
607 $inputType = $tmp[0];
608 if (!empty($tmp[1])) {
609 $inputOption = $tmp[1];
611 if (!empty($tmp[2])) {
612 $savemethod = $tmp[2];
615 $out .=
'<input id="timestamp" type="hidden"/>' .
"\n";
616 } elseif (preg_match(
'/^(select|autocomplete)/', $inputType)) {
617 $tmp = explode(
':', $inputType);
618 $inputType = $tmp[0];
619 $loadmethod = $tmp[1];
620 if (!empty($tmp[2])) {
621 $savemethod = $tmp[2];
623 if (!empty($tmp[3])) {
626 } elseif (preg_match(
'/^textarea/', $inputType)) {
627 $tmp = explode(
':', $inputType);
628 $inputType = $tmp[0];
629 $rows = (empty($tmp[1]) ?
'8' : $tmp[1]);
630 $cols = (empty($tmp[2]) ?
'80' : $tmp[2]);
631 } elseif (preg_match(
'/^ckeditor/', $inputType)) {
632 $tmp = explode(
':', $inputType);
633 $inputType = $tmp[0];
635 if (!empty($tmp[2])) {
638 if (!empty($tmp[3])) {
641 if (!empty($tmp[4])) {
642 $savemethod = $tmp[4];
646 $out .=
'<input id="ckeditor_toolbar" value="' . $toolbar .
'" type="hidden"/>' .
"\n";
648 $inputType =
'textarea';
652 $out .=
'<input id="element_' . $htmlname .
'" value="' . $element .
'" type="hidden"/>' .
"\n";
653 $out .=
'<input id="table_element_' . $htmlname .
'" value="' . $table_element .
'" type="hidden"/>' .
"\n";
654 $out .=
'<input id="fk_element_' . $htmlname .
'" value="' . $fk_element .
'" type="hidden"/>' .
"\n";
655 $out .=
'<input id="loadmethod_' . $htmlname .
'" value="' . $loadmethod .
'" type="hidden"/>' .
"\n";
656 if (!empty($savemethod)) {
657 $out .=
'<input id="savemethod_' . $htmlname .
'" value="' . $savemethod .
'" type="hidden"/>' .
"\n";
659 if (!empty($ext_element)) {
660 $out .=
'<input id="ext_element_' . $htmlname .
'" value="' . $ext_element .
'" type="hidden"/>' .
"\n";
662 if (!empty($custommsg)) {
663 if (is_array($custommsg)) {
664 if (!empty($custommsg[
'success'])) {
665 $out .=
'<input id="successmsg_' . $htmlname .
'" value="' . $custommsg[
'success'] .
'" type="hidden"/>' .
"\n";
667 if (!empty($custommsg[
'error'])) {
668 $out .=
'<input id="errormsg_' . $htmlname .
'" value="' . $custommsg[
'error'] .
'" type="hidden"/>' .
"\n";
671 $out .=
'<input id="successmsg_' . $htmlname .
'" value="' . $custommsg .
'" type="hidden"/>' .
"\n";
674 if ($inputType ==
'textarea') {
675 $out .=
'<input id="textarea_' . $htmlname .
'_rows" value="' . $rows .
'" type="hidden"/>' .
"\n";
676 $out .=
'<input id="textarea_' . $htmlname .
'_cols" value="' . $cols .
'" type="hidden"/>' .
"\n";
678 $out .=
'<span id="viewval_' . $htmlname .
'" class="viewval_' . $inputType . ($button_only ?
' inactive' :
' active') .
'">' . $value .
'</span>' .
"\n";
679 $out .=
'<span id="editval_' . $htmlname .
'" class="editval_' . $inputType . ($button_only ?
' inactive' :
' active') .
' hideobject">' . (!empty($editvalue) ? $editvalue : $value) .
'</span>' .
"\n";
705 public function textwithtooltip($text, $htmltext, $tooltipon = 1, $direction = 0, $img =
'', $extracss =
'', $notabs = 3, $incbefore =
'', $noencodehtmltext = 0, $tooltiptrigger =
'', $forcenowrap = 0)
708 $text = $incbefore . $text;
713 $direction = (int) $direction;
723 $htmltext = str_replace(array(
"\r",
"\n"),
'', $htmltext);
726 if ($direction < 0) {
727 $extracss = ($extracss ? $extracss :
'') . ($notabs != 3 ?
' inline-block' :
'');
728 $extrastyle =
'padding: 0px; padding-left: 2px;';
730 if ($direction > 0) {
731 $extracss = ($extracss ? $extracss :
'') . ($notabs != 3 ?
' inline-block' :
'');
732 $extrastyle =
'padding: 0px; padding-right: 2px;';
735 $classfortooltip =
'classfortooltip';
740 if ($tooltiptrigger ==
'') {
741 $htmltext = str_replace(
'"',
'"', $htmltext);
743 $classfortooltip =
'classfortooltiponclick';
744 $textfordialog .=
'<div style="display: none;" id="idfortooltiponclick_' . $tooltiptrigger .
'" class="classfortooltiponclicktext"';
748 $textfordialog .=
' title="'.$langs->trans(
"Note").
'"';
750 $textfordialog .=
'>' . $htmltext .
'</div>';
752 if ($tooltipon == 2 || $tooltipon == 3) {
753 $paramfortooltipimg =
' class="' . $classfortooltip . ($notabs != 3 ?
' inline-block' :
'') . ($extracss ?
' ' . $extracss :
'') .
'" style="padding: 0px;' . ($extrastyle ?
' ' . $extrastyle :
'') .
'"';
754 if ($tooltiptrigger ==
'') {
755 $paramfortooltipimg .=
' title="' . ($noencodehtmltext ? $htmltext :
dol_escape_htmltag($htmltext, 1, 0,
'span', 0, 1)) .
'"';
757 $paramfortooltipimg .=
' dolid="' . $tooltiptrigger .
'"';
760 $paramfortooltipimg = ($extracss ?
' class="' . $extracss .
'"' :
'') . ($extrastyle ?
' style="' . $extrastyle .
'"' :
'');
762 if ($tooltipon == 1 || $tooltipon == 3) {
763 $paramfortooltiptd =
' class="' . ($tooltipon == 3 ?
'cursorpointer ' :
'') . $classfortooltip . ($tag !=
'td' ?
' inline-block' :
'') . ($extracss ?
' ' . $extracss :
'') .
'" style="padding: 0px;' . ($extrastyle ?
' ' . $extrastyle :
'') .
'" ';
764 if ($tooltiptrigger ==
'') {
765 $paramfortooltiptd .=
' title="' . ($noencodehtmltext ? $htmltext :
dol_escape_htmltag($htmltext, 1, 0,
'span', 0, 1)) .
'"';
767 $paramfortooltiptd .=
' dolid="' . $tooltiptrigger .
'"';
770 $paramfortooltiptd = ($extracss ?
' class="' . $extracss .
'"' :
'') . ($extrastyle ?
' style="' . $extrastyle .
'"' :
'');
772 if (empty($notabs)) {
773 $s .=
'<table class="nobordernopadding"><tr style="height: auto;">';
774 } elseif ($notabs == 2) {
775 $s .=
'<div class="inline-block' . ($forcenowrap ?
' nowrap' :
'') .
'">';
778 if ($direction < 0) {
779 $s .=
'<' . $tag . $paramfortooltipimg;
781 $s .=
' class="valigntop" width="14"';
783 $s .=
'>' . $textfordialog . $img .
'</' . $tag .
'>';
787 if ((
string) $text !=
'') {
788 $s .=
'<' . $tag . $paramfortooltiptd .
'>' . $text .
'</' . $tag .
'>';
791 if ($direction > 0) {
792 $s .=
'<' . $tag . $paramfortooltipimg;
794 $s .=
' class="valignmiddle" width="14"';
796 $s .=
'>' . $textfordialog . $img .
'</' . $tag .
'>';
798 if (empty($notabs)) {
799 $s .=
'</tr></table>';
800 } elseif ($notabs == 2) {
821 public function textwithpicto($text, $htmltooltip, $direction = 1, $type =
'help', $extracss =
'valignmiddle', $noencodehtmltext = 0, $notabs = 3, $tooltiptrigger =
'', $forcenowrap = 0)
823 global
$conf, $langs;
828 } elseif ($type ==
'1') {
832 $tooltiptrigger = preg_replace(
'/[^a-z0-9]/i',
'', $tooltiptrigger);
834 if (preg_match(
'/onsmartphone$/', $tooltiptrigger) && empty(
$conf->dol_no_mouse_hover)) {
835 $tooltiptrigger = preg_replace(
'/^.*onsmartphone$/',
'', $tooltiptrigger);
838 if ($tooltiptrigger) {
839 $alt = $langs->transnoentitiesnoconv(
"ClickToShowHelp");
843 if (empty(
$conf->use_javascript_ajax)) {
844 if ($type ==
'info' || $type ==
'infoclickable' || $type ==
'help' || $type ==
'helpclickable') {
853 if (!empty(
$conf->dol_no_mouse_hover) && empty($tooltiptrigger)) {
854 if ($type ==
'info' || $type ==
'infoclickable' || $type ==
'help' || $type ==
'helpclickable') {
865 if ($type ==
'info') {
866 $img = img_help(($tooltiptrigger !=
'' ? 2 : 0), $alt);
867 } elseif ($type ==
'help') {
868 $img = img_help(($tooltiptrigger !=
'' ? 2 : 1), $alt);
869 } elseif ($type ==
'helpclickable') {
870 $img = img_help(($tooltiptrigger !=
'' ? 2 : 1), $alt);
871 } elseif ($type ==
'warning') {
872 $img = img_warning($alt);
873 } elseif ($type !=
'none') {
875 $img = img_picto($alt, $type);
878 $tooltipon = ((($tooltiptrigger && !$img) || strpos($type,
'clickable')) ? 3 : 2);
880 return $this->
textwithtooltip($text, $htmltooltip, $tooltipon, $direction, $img, $extracss, $notabs,
'', $noencodehtmltext, $tooltiptrigger, $forcenowrap);
893 public function selectMassAction($selected, $arrayofaction, $alwaysvisible = 0, $name =
'massaction', $cssclass =
'checkforselect')
895 global
$conf, $langs, $hookmanager;
898 $ret =
'<div class="centpercent center">';
899 $ret .=
'<select class="flat' . (empty(
$conf->use_javascript_ajax) ?
'' :
' hideobject') .
' ' . $name .
' ' . $name .
'select valignmiddle alignstart" id="' . $name .
'" name="' . $name .
'"' . ($disabled ?
' disabled="disabled"' :
'') .
'>';
902 $parameters = array();
903 $reshook = $hookmanager->executeHooks(
'addMoreMassActions', $parameters);
906 if (is_array($arrayofaction) && count($arrayofaction) == 0 && empty($hookmanager->resPrint)) {
909 if (empty($reshook)) {
910 $ret .=
'<option value="0"' . ($disabled ?
' disabled="disabled"' :
'') .
'>-- ' . $langs->trans(
"SelectAction") .
' --</option>';
911 if (is_array($arrayofaction)) {
912 foreach ($arrayofaction as $code => $label) {
913 $ret .=
'<option value="' . $code .
'"' . ($disabled ?
' disabled="disabled"' :
'') .
' data-html="' .
dol_escape_htmltag($label) .
'">' . $label .
'</option>';
917 $ret .= $hookmanager->resPrint;
921 if (empty(
$conf->dol_optimize_smallscreen)) {
926 $ret .=
'<input type="submit" name="confirmmassactioninvisible" style="display: none" tabindex="-1">';
927 $ret .=
'<input type="submit" disabled name="confirmmassaction"' . (empty(
$conf->use_javascript_ajax) ?
'' :
' style="display: none"') .
' class="reposition button smallpaddingimp' . (empty(
$conf->use_javascript_ajax) ?
'' :
' hideobject') .
' ' . $name .
' ' . $name .
'confirmed" value="' .
dol_escape_htmltag($langs->trans(
"Confirm")) .
'">';
930 if (!empty(
$conf->use_javascript_ajax)) {
931 $ret .=
'<!-- JS CODE TO ENABLE mass action select -->
933 function initCheckForSelect(mode, name, cssclass) { /* mode is 0 during init of page or click all, 1 when we click on 1 checkboxi, "name" refers to the class of the massaction button, "cssclass" to the class of the check for select boxes */
934 atleastoneselected=0;
935 jQuery("."+cssclass).each(function( index ) {
936 /* console.log( index + ": " + $( this ).text() ); */
937 if ($(this).is(\':checked\')) atleastoneselected++;
940 console.log("initCheckForSelect mode="+mode+" name="+name+" cssclass="+cssclass+" atleastoneselected="+atleastoneselected);
942 if (atleastoneselected || ' . ((int) $alwaysvisible) .
') {
943 jQuery("."+name).show();
944 ' . ($selected ?
'if (atleastoneselected) { jQuery("."+name+"select").val("' . $selected .
'").trigger(\'change\'); jQuery("."+name+"confirmed").prop(\'disabled\', false); }' :
'') .
'
945 ' . ($selected ?
'if (! atleastoneselected) { jQuery("."+name+"select").val("0").trigger(\'change\'); jQuery("."+name+"confirmed").prop(\'disabled\', true); } ' :
'') .
'
947 jQuery("."+name).hide();
948 jQuery("."+name+"other").hide();
952 jQuery(document).ready(function () {
953 initCheckForSelect(0, "' . $name .
'", "' . $cssclass .
'");
954 jQuery(".' . $cssclass .
'").change(function() {
955 console.log("A change was done on .' . $cssclass .
'");
956 initCheckForSelect(1, "' . $name .
'", "' . $cssclass .
'");
958 jQuery(".' . $name .
'select").change(function() {
959 var massaction = $( this ).val();
960 var urlform = $( this ).closest("form").attr("action").replace("#show_files","");
961 if (massaction == "builddoc") {
962 urlform = urlform + "#show_files";
964 $( this ).closest("form").attr("action", urlform);
965 console.log("we select a mass action name=' . $name .
' massaction="+massaction+" - "+urlform);
966 /* Warning: if you set submit button to disabled, post using Enter will no more work if there is no other button */
967 if ($(this).val() != \'0\') {
968 jQuery(".' . $name .
'confirmed").prop(\'disabled\', false);
969 jQuery(".' . $name .
'other").hide(); /* To disable if another div was open */
970 jQuery(".' . $name .
'"+massaction).show();
972 jQuery(".' . $name .
'confirmed").prop(\'disabled\', true);
973 jQuery(".' . $name .
'other").hide(); /* To disable any div open */
1003 public function select_country($selected =
'', $htmlname =
'country_id', $htmloption =
'', $maxlength = 0, $morecss =
'minwidth300', $usecodeaskey =
'', $showempty = 1, $disablefavorites = 0, $addspecialentries = 0, $exclude_country_code = array(), $hideflags = 0, $forcecombo = 0)
1008 $langs->load(
"dict");
1010 $selected = (string) $selected;
1014 $countryArray = array();
1015 $favorite = array();
1017 $atleastonefavorite = 0;
1019 $sql =
"SELECT rowid, code as code_iso, code_iso as code_iso3, label, favorite, eec";
1020 $sql .=
" FROM " . $this->db->prefix() .
"c_country";
1021 $sql .=
" WHERE active > 0";
1024 dol_syslog(get_class($this) .
"::select_country", LOG_DEBUG);
1026 $resql = $this->db->query($sql);
1028 $out .=
'<select id="select' . $htmlname .
'" class="flat maxwidth200onsmartphone selectcountry' . ($morecss ?
' ' . $morecss :
'') .
'" name="' . $htmlname .
'" ' . $htmloption .
'>';
1029 $num = $this->db->num_rows($resql);
1033 $obj = $this->db->fetch_object($resql);
1037 'rowid' => (
int) $obj->rowid,
1038 'code_iso' => (
string) $obj->code_iso,
1039 'code_iso3' => (
string) $obj->code_iso3,
1040 'label' => (
string) ($obj->code_iso && $langs->transnoentitiesnoconv(
"Country" . $obj->code_iso) !=
"Country" . $obj->code_iso ? $langs->transnoentitiesnoconv(
"Country" . $obj->code_iso) : ($obj->label !=
'-' ? $obj->label :
'')),
1041 'favorite' => (string) $obj->favorite,
1042 'eec' => (string) $obj->eec,
1044 $favorite[$i] = $obj->favorite;
1049 if (empty($disablefavorites)) {
1050 $array1_sort_order = SORT_DESC;
1051 $array2_sort_order = SORT_ASC;
1052 array_multisort($favorite, $array1_sort_order, $label, $array2_sort_order, $countryArray);
1058 if (is_numeric($showempty)) {
1059 $out .=
'<option value=""> </option>' .
"\n";
1061 $out .=
'<option value="-1">' . $langs->trans($showempty) .
'</option>' .
"\n";
1065 if ($addspecialentries) {
1067 $out .=
'<option value="special_allnotme"' . ($selected ==
'special_allnotme' ?
' selected' :
'') .
'>' . $langs->trans(
"CountriesExceptMe", $langs->transnoentitiesnoconv(
"Country" .
$mysoc->country_code)) .
'</option>';
1068 $out .=
'<option value="special_eec"' . ($selected ==
'special_eec' ?
' selected' :
'') .
'>' . $langs->trans(
"CountriesInEEC") .
'</option>';
1070 $out .=
'<option value="special_eecnotme"' . ($selected ==
'special_eecnotme' ?
' selected' :
'') .
'>' . $langs->trans(
"CountriesInEECExceptMe", $langs->transnoentitiesnoconv(
"Country" .
$mysoc->country_code)) .
'</option>';
1072 $out .=
'<option value="special_noteec"' . ($selected ==
'special_noteec' ?
' selected' :
'') .
'>' . $langs->trans(
"CountriesNotInEEC") .
'</option>';
1073 $out .=
'<option value="" disabled class="selectoptiondisabledwhite">------------</option>';
1076 foreach ($countryArray as $row) {
1078 if (empty($row[
'rowid'])) {
1081 if (is_array($exclude_country_code) && count($exclude_country_code) && in_array($row[
'code_iso'], $exclude_country_code)) {
1085 if (empty($disablefavorites) && $row[
'favorite'] && $row[
'code_iso']) {
1086 $atleastonefavorite++;
1088 if (empty($row[
'favorite']) && $atleastonefavorite) {
1089 $atleastonefavorite = 0;
1090 $out .=
'<option value="" disabled class="selectoptiondisabledwhite">------------</option>';
1094 if ($row[
'label']) {
1095 $labeltoshow .=
dol_trunc($row[
'label'], $maxlength,
'middle');
1097 $labeltoshow .=
' ';
1099 if ($row[
'code_iso']) {
1100 $labeltoshow .=
' <span class="opacitymedium">(' . $row[
'code_iso'] .
')</span>';
1101 if (empty($hideflags)) {
1102 $tmpflag =
picto_from_langcode($row[
'code_iso'],
'class="saturatemedium paddingrightonly"', 1);
1103 $labeltoshow = $tmpflag .
' ' . $labeltoshow;
1107 if ($selected && $selected !=
'-1' && ($selected == $row[
'rowid'] || $selected == $row[
'code_iso'] || $selected == $row[
'code_iso3'] || $selected == $row[
'label'])) {
1108 $out .=
'<option value="' . ($usecodeaskey ? ($usecodeaskey ==
'code2' ? $row[
'code_iso'] : $row[
'code_iso3']) : $row[
'rowid']) .
'" selected data-html="' .
dol_escape_htmltag($labeltoshow) .
'" data-eec="' . ((int) $row[
'eec']) .
'">';
1110 $out .=
'<option value="' . ($usecodeaskey ? ($usecodeaskey ==
'code2' ? $row[
'code_iso'] : $row[
'code_iso3']) : $row[
'rowid']) .
'" data-html="' .
dol_escape_htmltag($labeltoshow) .
'" data-eec="' . ((int) $row[
'eec']) .
'">';
1113 $out .=
'</option>' .
"\n";
1116 $out .=
'</select>';
1118 dol_print_error($this->db);
1122 if (empty($forcecombo)) {
1123 include_once DOL_DOCUMENT_ROOT .
'/core/lib/ajax.lib.php';
1124 $out .=
ajax_combobox(
'select' . $htmlname, array(), 0, 0,
'resolve');
1140 public function selectPhoneCode($selected =
'', $htmlname =
'phone_code', $morecss =
'maxwidth150', $showempty = 0, $country_id_hint = 0)
1144 $langs->load(
"dict");
1147 $codeArray = array();
1148 $favorite = array();
1150 $atleastonefavorite = 0;
1152 $sql =
"SELECT rowid, code, label, phone_code, favorite, trunk_prefix";
1153 $sql .=
" FROM ".$this->db->prefix().
"c_country";
1155 $sql .=
" WHERE active > 0 AND phone_code IS NOT NULL AND phone_code != 0";
1157 dol_syslog(get_class($this).
"::selectPhoneCode", LOG_DEBUG);
1158 $resql = $this->db->query($sql);
1160 $num = $this->db->num_rows($resql);
1163 $obj = $this->db->fetch_object($resql);
1165 $translabel = ($obj->code && $langs->transnoentitiesnoconv(
"Country".$obj->code) !=
"Country".$obj->code) ? $langs->transnoentitiesnoconv(
"Country".$obj->code) : $obj->label;
1167 $codeArray[$i][
'rowid'] = $obj->rowid;
1168 $codeArray[$i][
'code'] = $obj->code;
1169 $codeArray[$i][
'label'] = $translabel;
1170 $codeArray[$i][
'phone_code'] =
'+'.$obj->phone_code;
1171 $codeArray[$i][
'favorite'] = $obj->favorite;
1172 $codeArray[$i][
'trunk_prefix'] = $obj->trunk_prefix;
1173 $favorite[$i] = $obj->favorite;
1178 $array1_sort_order = SORT_DESC;
1179 $array2_sort_order = SORT_ASC;
1180 array_multisort($favorite, $array1_sort_order, $label, $array2_sort_order, $codeArray);
1182 $out .=
'<select id="select'.$htmlname.
'" class="flat selectphonecode'.($morecss ?
' '.$morecss :
'').
'" name="'.$htmlname.
'">';
1185 $out .=
'<option value=""> </option>'.
"\n";
1190 $firstMatchIdx = -1;
1191 if ($selected !==
'') {
1192 foreach ($codeArray as $idx => $row) {
1193 if ($row[
'phone_code'] == $selected) {
1194 if ($firstMatchIdx < 0) {
1195 $firstMatchIdx = $idx;
1197 if ($country_id_hint > 0 && $row[
'rowid'] == $country_id_hint) {
1198 $selectedIdx = $idx;
1203 if ($selectedIdx < 0 && $firstMatchIdx >= 0) {
1204 $selectedIdx = $firstMatchIdx;
1208 foreach ($codeArray as $idx => $row) {
1209 if (empty($row[
'code'])) {
1213 if ($row[
'favorite']) {
1214 $atleastonefavorite++;
1216 if (empty($row[
'favorite']) && $atleastonefavorite) {
1217 $atleastonefavorite = 0;
1218 $out .=
'<option value="" disabled class="selectoptiondisabledwhite">------------</option>';
1221 $tmpflag =
picto_from_langcode($row[
'code'],
'class="saturatemedium paddingrightonly"', 1);
1224 $selectlabel = ($tmpflag ? $tmpflag.
' ' :
'').$row[
'code'];
1227 $labeltoshow = ($tmpflag ? $tmpflag.
' ' :
'').$row[
'label'].
' '.$row[
'phone_code'];
1229 $out .=
'<option value="'.dol_escape_htmltag($row[
'phone_code']).
'"';
1230 if ($idx === $selectedIdx) {
1231 $out .=
' selected';
1233 $out .=
' data-html="'.dol_escape_htmltag($labeltoshow).
'"';
1234 $out .=
' data-select-html="'.dol_escape_htmltag($selectlabel).
'"';
1235 $out .=
' data-country-id="'.((int) $row[
'rowid']).
'"';
1236 $out .=
' data-trunk-prefix="'.dol_escape_htmltag((
string) $row[
'trunk_prefix']).
'"';
1239 $out .=
'</option>'.
"\n";
1241 $out .=
'</select>';
1243 dol_print_error($this->db);
1247 include_once DOL_DOCUMENT_ROOT.
'/core/lib/ajax.lib.php';
1248 $out .=
ajax_combobox(
'select'.$htmlname, array(), 0, 0,
'resolve');
1269 public function showPhoneInput($phoneValue, $htmlname, $country_id_hint = 0, $picto =
'object_phoning', $morecss =
'maxwidth150', $maxlength = 0, $countrySelectorId =
'selectcountry_id')
1273 include_once DOL_DOCUMENT_ROOT.
'/core/lib/phone.lib.php';
1275 $codename = $htmlname.
'_code';
1278 if (empty($country_id_hint) && !empty(
$mysoc->country_id)) {
1279 $country_id_hint =
$mysoc->country_id;
1284 $fullPhone = (string)
GETPOST($htmlname);
1286 $fullPhone = (string) $phoneValue;
1295 $selectedCode = $phonecode;
1296 $numberValue = $parsed[
'number'];
1299 if (strpos($numberValue, $selectedCode) === 0) {
1300 $numberValue = str_replace($selectedCode,
'', $numberValue);
1304 if ($numberValue !==
'' && $selectedCode !==
'') {
1306 if ($trunkPrefix !==
'' && strpos($numberValue, $trunkPrefix) !== 0) {
1307 $numberValue = $trunkPrefix.$numberValue;
1315 $out .= img_picto(
'', $picto,
'class="pictofixedwidth"');
1318 $out .= $this->
selectPhoneCode($selectedCode, $codename,
'maxwidth75 phone_code_select', 0, $country_id_hint);
1321 $out .=
'<input type="tel" inputmode="numeric" pattern="[0-9]*" id="'.dol_escape_htmltag($htmlname).
'_input" class="'.
dol_escape_htmltag($morecss).
'"';
1322 if ($maxlength > 0) {
1323 $out .=
' maxlength="'.$maxlength.
'"';
1325 $out .=
' value="'.dol_escape_htmltag($numberValue).
'">';
1350 $selectId =
'select'.dol_escape_js($codename);
1352 $out =
"\n".
'<script type="text/javascript">'.
"\n";
1353 $out .=
'jQuery(document).ready(function() {'.
"\n";
1354 $out .=
' function syncPhoneField_'.$hiddenId.
'() {'.
"\n";
1355 $out .=
' var selectEl = jQuery(\'#'.$selectId.
'\');
'."\n";
1356 $out .= ' var code = selectEl.val() ||
"";
'."\n";
1357 $out .= ' var number = (jQuery(\
'#'.$inputId.
'\').val() ||
"").replace(/[^0-9]/g,
"");
'."\n";
1358 $out .= ' if (code && number) {
'."\n";
1359 $out .= ' var selOpt = selectEl[0] && selectEl[0].selectedOptions && selectEl[0].selectedOptions[0];
'."\n";
1360 $out .= ' var trunkPrefix = selOpt ? (selOpt.getAttribute(
"data-trunk-prefix") ||
"") :
"";
'."\n";
1361 $out .= ' if (trunkPrefix !==
"" && number.indexOf(trunkPrefix) === 0) {
'."\n";
1362 $out .= ' number = number.substring(trunkPrefix.length);
'."\n";
1364 $out .= ' jQuery(
"#'.$hiddenId.'").val(code +
" " + number);
'."\n";
1365 $out .= ' }
else if (number) {
'."\n";
1366 $out .= ' jQuery(
"#'.$hiddenId.'").val(number);
'."\n";
1367 $out .= ' }
else {
'."\n";
1368 $out .= ' jQuery(
"#'.$hiddenId.'").val(
"");
'."\n";
1371 $out .= ' jQuery(\
'#'.$selectId.
'\').on(
"change",
function() { syncPhoneField_
'.$hiddenId.'(); });
'."\n";
1372 $out .= ' jQuery(\
'#'.$inputId.
'\').on(
"input change",
function() { syncPhoneField_
'.$hiddenId.'(); });
'."\n";
1374 $out .= '</script>
'."\n";
1388 private function getPhoneInputSharedJs($countrySelectorId)
1390 if ($this->phoneInputSharedJsLoaded) {
1393 $this->phoneInputSharedJsLoaded = true;
1395 $out = "\n".'<script
type=
"text/javascript">
'."\n";
1396 $out .= 'jQuery(document).ready(
function() {
'."\n";
1397 $out .= ' jQuery(\
'#'.
dol_escape_js($countrySelectorId).
'\').on(
"change",
function() {
'."\n";
1398 $out .= ' var country_id = jQuery(
this).val();
'."\n";
1399 $out .= ' if (country_id) {
'."\n";
1400 $out .= ' jQuery.getJSON(
"'.DOL_URL_ROOT.'/core/ajax/getphonecode.php", {country_id: country_id, token:
"'.currentToken().'"},
function(data) {
'."\n";
1401 $out .= ' if (data.phone_code) {
'."\n";
1402 $out .= ' jQuery(
".phone_code_select").each(
function() {
'."\n";
1403 $out .= ' jQuery(
this).val(data.phone_code).trigger(
"change");
'."\n";
1404 $out .= ' });
'."\n";
1406 $out .= ' });
'."\n";
1408 $out .= ' });
'."\n";
1410 $out .= '</script>
'."\n";
1428 private function makeAddLinkToObject($object, $key, $possiblelink, $num, $resqllist)
1430 dol_syslog(__METHOD__, LOG_DEBUG);
1431 global $langs, $form;
1433 $form = new Form($this->db);
1435 $htmltoenteralink = '
';
1439 $htmltoenteralink .= '<tr
class=
"liste_titre">
';
1440 $htmltoenteralink .= '<td
class=
"nowrap"></td>
';
1441 $htmltoenteralink .= '<td>
' . $langs->trans("Ref") . '</td>
';
1442 $htmltoenteralink .= '<td>
' . $langs->trans("RefCustomer") . '</td>
';
1443 $htmltoenteralink .= '<td
class=
"right">
' . $langs->trans("AmountHTShort") . '</td>
';
1444 $htmltoenteralink .= '<td>
' . $langs->trans("Company") . '</td>
';
1445 $htmltoenteralink .= '</tr>
';
1449 $objp = $this->db->fetch_object($resqllist);
1450 $alreadylinked = false;
1451 if (!empty($object->linkedObjectsIds[$possiblelink['linkname
'] ?? $key])) {
1452 if (in_array($objp->rowid, array_values($object->linkedObjectsIds[$possiblelink['linkname
'] ?? $key]))) {
1453 $alreadylinked = true;
1456 $htmltoenteralink .= '<tr
class=
"oddeven">
';
1457 $htmltoenteralink .= '<td>
';
1458 if ($alreadylinked) {
1459 $htmltoenteralink .= img_picto('', 'link
');
1461 $htmltoenteralink .= '<input
type=
"checkbox" name=
"idtolinkto[' . $key . '_' . $objp->rowid . ']" id=
"' . $key . '_' . $objp->rowid . '" value=
"' . $objp->rowid . '">
';
1463 $htmltoenteralink .= '</td>
';
1464 $htmltoenteralink .= '<td>
';
1465 if (!$alreadylinked) {
1466 $htmltoenteralink .= '<label
for=
"' . $key . '_' . $objp->rowid . '">
';
1468 $htmltoenteralink .= $objp->ref;
1469 if (!$alreadylinked) {
1470 $htmltoenteralink .= '</label>
';
1472 $htmltoenteralink .= '</td>
';
1473 $htmltoenteralink .= '<td>
' . (!empty($objp->ref_client) ? $objp->ref_client : (!empty($objp->ref_supplier) ? $objp->ref_supplier : '')) . '</td>
';
1474 $htmltoenteralink .= '<td
class=
"right">
';
1475 if ($possiblelink['label
'] == 'LinkToContract
') {
1476 $htmltoenteralink .= $form->textwithpicto('', $langs->trans("InformationOnLinkToContract")) . ' ';
1478 $htmltoenteralink .= '<span
class=
"amount">
' . (isset($objp->total_ht) ? price($objp->total_ht) : '') . '</span>
';
1479 $htmltoenteralink .= '</td>
';
1480 $htmltoenteralink .= '<td>
' . $objp->name . '</td>
';
1481 $htmltoenteralink .= '</tr>
';
1485 return $htmltoenteralink;
1502 private function makeAddLinkToAttendee($object, $key, $possiblelink, $num, $resqllist)
1504 dol_syslog(__METHOD__, LOG_DEBUG);
1505 global $langs, $form;
1506 require_once DOL_DOCUMENT_ROOT . '/eventorganization/
class/conferenceorboothattendee.class.php
';
1507 require_once DOL_DOCUMENT_ROOT . '/societe/
class/societe.class.php
';
1508 require_once DOL_DOCUMENT_ROOT . '/projet/
class/project.class.php
';
1509 $attendeestatic = new ConferenceOrBoothAttendee($this->db);
1510 $companystatic = new Societe($this->db);
1511 $projectstatic = new Project($this->db);
1513 $form = new Form($this->db);
1515 $htmltoenteralink = '';
1519 $htmltoenteralink .= '<tr
class=
"liste_titre">
';
1520 $htmltoenteralink .= '<td
class=
"nowrap"></td>
';
1521 $htmltoenteralink .= '<td>
' . $langs->trans("Ref") . '</td>
';
1522 $htmltoenteralink .= '<td>
' . $langs->trans("Name") . '</td>
';
1523 $htmltoenteralink .= '<td>
' . $langs->trans("Email") . '</td>
';
1524 $htmltoenteralink .= '<td>
' . $langs->trans("Company") . '</td>
';
1525 $htmltoenteralink .= '<td>
' . $langs->trans("Project") . '</td>
';
1526 $htmltoenteralink .= '<td>
' . $langs->trans("DateOfRegistration") . '</td>
';
1527 $htmltoenteralink .= '</tr>
';
1531 $objp = $this->db->fetch_object($resqllist);
1532 $alreadylinked = false;
1533 if (!empty($object->linkedObjectsIds[$possiblelink['linkname
'] ?? $key])) {
1534 if (in_array($objp->rowid, array_values($object->linkedObjectsIds[$possiblelink['linkname
'] ?? $key]))) {
1535 $alreadylinked = true;
1538 $htmltoenteralink .= '<tr
class=
"oddeven">
';
1539 $htmltoenteralink .= '<td>
';
1540 if ($alreadylinked) {
1541 $htmltoenteralink .= img_picto('', 'link
');
1543 $htmltoenteralink .= '<input
type=
"checkbox" name=
"idtolinkto[' . $key . '_' . $objp->rowid . ']" id=
"' . $key . '_' . $objp->rowid . '" value=
"' . $objp->rowid . '">
';
1545 $htmltoenteralink .= '</td>
';
1546 $fetchattendee = $attendeestatic->fetch($objp->rowid);
1547 if ($fetchattendee) {
1548 $htmltoenteralink .= '<td>
' . $attendeestatic->getNomUrl(0). '</td>
';
1550 $htmltoenteralink .= '<td><label
for=
"' . $key . '_' . $objp->rowid . '">
' . $objp->ref . '</label></td>
';
1552 $htmltoenteralink .= '<td>
' . $objp->name . '</td>
';
1553 $htmltoenteralink .= '<td>
' . $objp->email . '</td>
';
1554 $fetchcompany = $companystatic->fetch($objp->socid);
1555 if ($fetchcompany) {
1556 $htmltoenteralink .= '<td>
' . $companystatic->getNomUrl(0). '</td>
';
1558 $htmltoenteralink .= '<td>
' . $objp->name . '</td>
';
1560 $fetchcproject = $projectstatic->fetch($objp->fk_project);
1561 if ($fetchcproject) {
1562 $htmltoenteralink .= '<td>
' . $projectstatic->getNomUrl(0). '</td>
';
1564 $htmltoenteralink .= '<td>
' . $objp->fk_project . '</td>
';
1566 $htmltoenteralink .= '<td>
' . $objp->date_subscription . '</td>
';
1567 $htmltoenteralink .= '</tr>
';
1571 return $htmltoenteralink;
1574 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1589 public function select_incoterms($selected = '
', $location_incoterms = '', $page = '', $htmlname = 'incoterm_id
', $htmloption = '', $forcecombo = 1, $events = array(), $disableautocomplete = 0)
1592 global $conf, $langs;
1594 $langs->load("dict");
1598 $incotermArray = array();
1600 $sql = "SELECT rowid, code";
1601 $sql .= " FROM " . $this->db->prefix() . "c_incoterms";
1602 $sql .= " WHERE active > 0";
1603 $sql .= " ORDER BY code ASC";
1605 dol_syslog(get_class($this) . "::select_incoterm", LOG_DEBUG);
1606 $resql = $this->db->query($sql);
1608 if ($conf->use_javascript_ajax && !$forcecombo) {
1609 include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php
';
1610 $out .= ajax_combobox($htmlname, $events);
1613 if (!empty($page)) {
1614 $out .= '<form method=
"post" action=
"' . $page . '">
';
1615 $out .= '<input
type=
"hidden" name=
"action" value=
"set_incoterms">
';
1616 $out .= '<input
type=
"hidden" name=
"token" value=
"' . newToken() . '">
';
1619 $out .= '<select
id=
"' . $htmlname . '" class=
"flat selectincoterm width75" name=
"' . $htmlname . '" ' . $htmloption . '>
';
1620 $out .= '<option value=
"0"> </option>
';
1621 $num = $this->db->num_rows($resql);
1625 $obj = $this->db->fetch_object($resql);
1626 $incotermArray[$i]['rowid
'] = $obj->rowid;
1627 $incotermArray[$i]['code
'] = $obj->code;
1631 foreach ($incotermArray as $row) {
1632 if ($selected && ($selected == $row['rowid
'] || $selected == $row['code
'])) {
1633 $out .= '<option value=
"' . $row['rowid'] . '" selected>
';
1635 $out .= '<option value=
"' . $row['rowid'] . '">
';
1639 $out .= $row['code
'];
1642 $out .= '</option>
';
1645 $out .= '</select>
';
1646 $out .= ajax_combobox($htmlname);
1648 if ($conf->use_javascript_ajax && empty($disableautocomplete)) {
1649 $out .= ajax_multiautocompleter('location_incoterms
', array(), DOL_URL_ROOT . '/core/ajax/locationincoterms.php
') . "\n";
1650 //$moreattrib .= ' autocomplete=
"off"';
1652 $out .= '<input
id=
"location_incoterms" class=
"maxwidthonsmartphone heightofcombo" type=
"text" name=
"location_incoterms" value=
"' . $location_incoterms . '">
' . "\n";
1654 if (!empty($page)) {
1655 $out .= '<input
type=
"submit" class=
"button valignmiddle smallpaddingimp nomargintop nomarginbottom" value=
"' . $langs->trans("Modify
") . '"></form>
';
1658 dol_print_error($this->db);
1664 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1679 public function select_type_of_lines($selected = '
', $htmlname = 'type', $showempty = 0, $hidetext = 0, $forceall = 0, $morecss = "", $useajaxcombo = 1)
1684 // If product & services are enabled or both disabled.
1685 if ($forceall == 1 || (empty($forceall) && isModEnabled("product") && isModEnabled("service"))
1686 || (empty($forceall) && !isModEnabled('product
') && !isModEnabled('service
'))) {
1687 if (empty($hidetext)) {
1688 print $langs->trans("Type").'...
';
1691 print '<select
class=
"flat'.($morecss ? ' '.$morecss : '').'" id=
"select_' . $htmlname . '" name=
"' . $htmlname . '">
';
1693 print '<option value=
"-1" class=
"opacitymedium"'.($useajaxcombo ? '' : ' disabled=
"disabled"');
1694 if ($selected == -1) {
1698 if (is_numeric($showempty)) {
1706 print '<option value=
"0"';
1707 if (0 == $selected || ($selected == -1 && getDolGlobalString('MAIN_FREE_PRODUCT_CHECKED_BY_DEFAULT
') == 'product
')) {
1710 print '>
' . $langs->trans("Product");
1713 print '<option value=
"1"';
1714 if (1 == $selected || ($selected == -1 && getDolGlobalString('MAIN_FREE_PRODUCT_CHECKED_BY_DEFAULT
') == 'service
')) {
1717 print '>
' . $langs->trans("Service");
1722 if ($useajaxcombo) {
1723 print ajax_combobox('select_
' . $htmlname);
1725 //if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
1727 if ((empty($forceall) && !isModEnabled('product
') && isModEnabled("service")) || $forceall == 3) {
1728 print $langs->trans("Service");
1729 print '<input
type=
"hidden" name=
"' . $htmlname . '" value=
"1">
';
1731 if ((empty($forceall) && isModEnabled("product") && !isModEnabled('service
')) || $forceall == 2) {
1732 print $langs->trans("Product");
1733 print '<input
type=
"hidden" name=
"' . $htmlname . '" value=
"0">
';
1735 if ($forceall < 0) { // This should happened only for contracts when both predefined product and service are disabled.
1736 print '<input
type=
"hidden" name=
"' . $htmlname . '" value=
"1">
'; // By default we set on service for contract. If CONTRACT_SUPPORT_PRODUCTS is set, forceall should be 1 not -1
1740 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1747 public function load_cache_types_fees()
1752 $num = count($this->cache_types_fees);
1754 return 0; // Cache already loaded
1757 dol_syslog(__METHOD__, LOG_DEBUG);
1759 $langs->load("trips");
1761 $sql = "SELECT c.code, c.label";
1762 $sql .= " FROM " . $this->db->prefix() . "c_type_fees as c";
1763 $sql .= " WHERE active > 0";
1765 $resql = $this->db->query($sql);
1767 $num = $this->db->num_rows($resql);
1771 $obj = $this->db->fetch_object($resql);
1773 // If a translation exists, we use is, otherwise, we take the label by default
1774 $label = ($obj->code != $langs->trans($obj->code) ? $langs->trans($obj->code) : $langs->trans($obj->label));
1775 $this->cache_types_fees[$obj->code] = $label;
1779 asort($this->cache_types_fees);
1783 dol_print_error($this->db);
1788 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1801 public function select_type_fees($selected = '
', $htmlname = 'type', $showempty = 0, $morecss = '', $nooutput = 0, $noadmin = 0)
1804 global $user, $langs;
1806 dol_syslog(__METHOD__ . " selected=" . $selected . ", htmlname=" . $htmlname, LOG_DEBUG);
1808 $this->load_cache_types_fees();
1812 $out .= '<select
id=
"select_' . $htmlname . '" class=
"flat'.($morecss ? ' '.$morecss : '').'" name=
"' . $htmlname . '">
';
1814 $out .= '<option value=
"-1"';
1815 if ($selected === -1) {
1816 $out .= ' selected
';
1819 if (!is_numeric($showempty)) {
1820 $out .= $langs->trans($showempty);
1822 $out .= '</option>
';
1825 foreach ($this->cache_types_fees as $key => $value) {
1826 $out .= '<option value=
"' . $key . '"';
1827 if ($key == (string) $selected) {
1828 $out .= ' selected
';
1832 $out .= '</option>
';
1835 $out .= '</select>
';
1836 if ($user->admin && empty($noadmin)) {
1837 $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
1840 $out .= ajax_combobox('select_
'.$htmlname);
1842 if (empty($nooutput)) {
1851 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1875 public function select_company($selected = '
', $htmlname = 'socid
', $filter = '', $showempty = '', $showtype = 0, $forcecombo = 0, $events = array(), $limit = 0, $morecss = 'minwidth100
', $moreparam = '', $selected_input_value = '', $hidelabel = 1, $ajaxoptions = array(), $multiple = false, $excludeids = array(), $showcode = 0)
1878 global $conf, $langs;
1882 if (!empty($conf->use_javascript_ajax) && getDolGlobalString('COMPANY_USE_SEARCH_TO_SELECT
') && !$forcecombo) {
1883 if (is_null($ajaxoptions)) {
1884 $ajaxoptions = array();
1887 require_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php
';
1889 // No immediate load of all database
1891 if ($selected && empty($selected_input_value)) {
1892 require_once DOL_DOCUMENT_ROOT . '/societe/
class/societe.class.php
';
1893 $societetmp = new Societe($this->db);
1894 $societetmp->fetch($selected);
1895 $selected_input_value = $societetmp->name;
1900 $urloption = 'htmlname=
' . urlencode((string) (str_replace('.
', '_
', $htmlname))) . '&outjson=1&filter=
' . urlencode((string) ($filter)) . (empty($excludeids) ? '' : '&excludeids=
' . implode(',
', $excludeids)) . ($showtype ? '&showtype=
' . urlencode((string) ($showtype)) : '') . ($showcode ? '&showcode=
' . urlencode((string) ($showcode)) : '') . ($limit ? '&limit=
'.$limit : '');
1902 $out .= '<!-- force css to be higher than dialog popup --><style
type=
"text/css">.ui-autocomplete { z-index: 1010; }</style>
';
1903 if (empty($hidelabel)) {
1904 $out .= $langs->trans("RefOrLabel") . ' :
';
1905 } elseif ($hidelabel == 1 && !is_numeric($showempty)) {
1906 $placeholder = $langs->trans($showempty);
1907 } elseif ($hidelabel > 1) {
1908 $placeholder = $langs->trans("RefOrLabel");
1909 if ($hidelabel == 2) {
1910 $out .= img_picto($langs->trans("Search"), 'search
');
1913 $out .= '<input
type=
"text" class=
"' . $morecss . '" name=
"search_' . $htmlname . '" id=
"search_' . $htmlname . '" value=
"' . $selected_input_value . '"' . ($placeholder ? ' placeholder=
"' . dol_escape_htmltag($placeholder) . '"' : '') . ' ' . (getDolGlobalString('THIRDPARTY_SEARCH_AUTOFOCUS
') ? 'autofocus
' : '') . ' spellcheck=
"false" />
';
1914 if ($hidelabel == 3) {
1915 $out .= img_picto($langs->trans("Search"), 'search
');
1918 $out .= ajax_event($htmlname, $events);
1920 $out .= ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/societe/ajax/company.php
', $urloption, getDolGlobalInt('COMPANY_USE_SEARCH_TO_SELECT
'), 0, $ajaxoptions);
1922 // Immediate load of all database
1923 $out .= $this->select_thirdparty_list($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events, '', 0, $limit, $morecss, $moreparam, $multiple, $excludeids, $showcode);
1930 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1958 public function select_contact($socid, $selected = '
', $htmlname = 'contactid
', $showempty = 0, $exclude = '', $limitto = '', $showfunction = 0, $morecss = '', $nokeyifsocid = true, $showsoc = 0, $forcecombo = 0, $events = array(), $moreparam = '', $htmlid = '', $selected_input_value = '', $filter = '', $multiple = false)
1962 global $conf, $langs;
1966 if (empty($htmlid)) {
1967 $htmlid = $htmlname;
1970 $sav = getDolGlobalString('CONTACT_USE_SEARCH_TO_SELECT
');
1971 if ($nokeyifsocid && $socid > 0) {
1972 $conf->global->CONTACT_USE_SEARCH_TO_SELECT = 0;
1975 if (!empty($conf->use_javascript_ajax) && getDolGlobalString('CONTACT_USE_SEARCH_TO_SELECT
') && !$forcecombo) {
1976 require_once DOL_DOCUMENT_ROOT . '/contact/
class/contact.class.php
';
1977 require_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php
';
1979 // select2 combo pre-filled with only the currently selected contact(s) as <option selected>.
1980 // select2 keeps those and fetches the rest on demand from contact/ajax/contact.php instead of
1981 // loading the whole contact list into the page.
1982 $selectedids = array();
1983 foreach (($multiple ? (is_array($selected) ? $selected : array()) : ($selected !== '' && $selected !== 0 ? array($selected) : array())) as $tmpid) {
1984 if (is_numeric($tmpid) && (int) $tmpid > 0) {
1985 $selectedids[] = (int) $tmpid;
1989 // A non-numeric $showempty ('
', a label, ...) is used as a select2 placeholder instead of
1990 // an <option> value; select2 needs an empty first <option> in single mode to be able to show it.
1991 $placeholder = is_numeric($showempty) ? '' : (string) $showempty;
1993 $out .= '<select
class=
"flat' . ($morecss ? ' ' . $morecss : '') . '" id=
"' . $htmlid . '" name=
"' . $htmlname . ($multiple ? '[]' : '') . '"' . ($multiple ? ' multiple
' : '') . ($moreparam ? ' ' . $moreparam : '') . '>
';
1995 $out .= '<option></option>
';
1997 if (count($selectedids)) {
1998 $contacttmp = new Contact($this->db);
1999 foreach ($selectedids as $tmpid) {
2000 if ($contacttmp->fetch($tmpid) > 0) {
2001 $out .= '<option value=
"' . $tmpid . '" selected>
' . dol_escape_htmltag($contacttmp->getFullName($langs)) . '</option>
';
2006 $out .= '</select>
';
2008 $out .= ajax_event($htmlname, $events);
2010 // Same as the value of 'htmlname=
' below: the endpoint reads the typed term from a GET param
2011 // named after this transformed htmlname (see contact/ajax/contact.php).
2012 $htmlnamefortermparam = str_replace('.
', '_
', $htmlname);
2013 $urloption = 'htmlname=
' . urlencode((string) $htmlnamefortermparam) . '&outjson=1&filter=
' . urlencode((string) $filter)
2014 . (empty($exclude) ? '' : '&exclude=
' . urlencode($exclude))
2015 . ($showsoc ? '&showsoc=
' . urlencode((string) $showsoc) : '')
2016 . ($socid > 0 ? '&socid=
' . ((int) $socid) : '');
2018 // A non-numeric value ('infinite
') means "infinite list": no minimum number of chars, the list
2019 // opens as soon as the field gets the focus (select2 queries the endpoint with an empty term).
2020 $minlengthforajax = getDolGlobalInt('CONTACT_USE_SEARCH_TO_SELECT
');
2021 if ($minlengthforajax < 1) {
2022 $minlengthforajax = 0;
2024 // Page size of the ajax endpoint (CONTACT_LIMIT_SIZE): select2 keeps asking for the next page
2025 // while the endpoint returns a full page, so the whole list stays browsable by scrolling.
2026 $ajaxpagesize = getDolGlobalInt('CONTACT_LIMIT_SIZE
', 20);
2028 $htmlidjs = str_replace('.
', '\\\\.
', $htmlid);
2029 $out .= '<script nonce=
"' . getNonce() . '">jQuery(
function() {
2030 jQuery(
"#' . $htmlidjs . '").select2({
2032 language: (typeof select2arrayoflanguage ===
"undefined") ?
"en" : select2arrayoflanguage,
2033 containerCssClass:
":all:",
2034 placeholder:
' . json_encode($placeholder) . ',
2035 minimumInputLength:
' . ((int) $minlengthforajax) . ',
2037 url:
"' . DOL_URL_ROOT . '/contact/ajax/contact.php?' . $urloption . '",
2040 data:
function(params) {
2042 d[
' . json_encode($htmlnamefortermparam) . '] = params.term;
2043 d.page = params.page || 1;
2046 processResults:
function(data) {
2048 jQuery.each(data,
function(i, val) {
2049 result.push({ id: val.key, text: val.value });
2051 return { results: result, pagination: { more: data.length >=
' . ((int) $ajaxpagesize) . ' } };
2055 });
' . (getDolGlobalString('CONTACT_SEARCH_AUTOFOCUS
') ? '
2056 jQuery(
"#' . $htmlidjs . '").select2(
"open");
' : '') . '
2058 $out .= '<!-- force css to be higher than dialog popup --><style
type=
"text/css">.select2-container { z-index: 1010; }</style>
';
2060 // Immediate load of all database
2061 $disableifempty = 0;
2065 $out .= $this->selectcontacts($socid, $selected, $htmlname, $showempty, $exclude, $limitto, $showfunction, $morecss, $options_only, $showsoc, $forcecombo, $events, $moreparam, $htmlid, $multiple, $disableifempty, $filter);
2068 $conf->global->CONTACT_USE_SEARCH_TO_SELECT = $sav;
2074 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2099 public function select_thirdparty_list($selected = '
', $htmlname = 'socid
', $filter = '', $showempty = '', $showtype = 0, $forcecombo = 0, $events = array(), $filterkey = '', $outputmode = 0, $limit = 0, $morecss = 'minwidth100
', $moreparam = '', $multiple = false, $excludeids = array(), $showcode = 0)
2102 global $user, $langs;
2103 global $hookmanager;
2105 $langs->loadLangs(array("companies", "suppliers"));
2109 $outarray = array();
2111 if ($selected === '') {
2112 $selected = array();
2113 } elseif (!is_array($selected)) {
2114 $selected = array($selected);
2117 // Clean $filter that may contains sql conditions so sql code
2119 if (testSqlAndScriptInject($filter, 3) > 0) {
2121 return 'SQLInjectionTryDetected
';
2125 if ($filter != '') { // If a filter was provided
2127 $filter = forgeSQLFromUniversalSearchCriteria($filter, $errormsg, 1);
2129 // Redo clean $filter that may contains sql conditions so sql code
2131 if (testSqlAndScriptInject($filter, 3) > 0) {
2133 return 'SQLInjectionTryDetected
';
2138 // We search companies
2139 $sql = "SELECT s.rowid, s.nom as name, s.name_alias, s.tva_intra, s.client, s.fournisseur, s.code_client, s.code_fournisseur";
2140 if (getDolGlobalString('COMPANY_SHOW_ADDRESS_SELECTLIST
')) {
2141 $sql .= ", s.address, s.zip, s.town";
2142 $sql .= ", dictp.code as country_code";
2144 $sql .= " FROM " . $this->db->prefix() . "societe as s";
2145 if (getDolGlobalString('COMPANY_SHOW_ADDRESS_SELECTLIST
')) {
2146 $sql .= " LEFT JOIN " . $this->db->prefix() . "c_country as dictp ON dictp.rowid = s.fk_pays";
2148 if (!$user->hasRight('societe
', 'client
', 'voir
')) {
2149 $sql .= ", " . $this->db->prefix() . "societe_commerciaux as sc";
2151 $sql .= " WHERE s.entity IN (" . getEntity('societe
') . ")";
2152 if (!empty($user->socid)) {
2153 $sql .= " AND s.rowid = " . ((int) $user->socid);
2156 // $filter is safe because, it has been tested by testSqlAndScriptInject() and sanitized by forgeSQLFromUniversalSearchCriteria()
2157 $sqlwhere = $filter; // @phan-suppress-current-line SqlInjection
2158 $sql .= " AND (" . $sqlwhere . ")";
2160 if (!$user->hasRight('societe
', 'client
', 'voir
')) {
2161 $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " . ((int) $user->id);
2163 if (getDolGlobalString('COMPANY_HIDE_INACTIVE_IN_COMBOBOX
')) {
2164 $sql .= " AND s.status <> 0";
2166 if (!empty($excludeids)) {
2167 $sql .= " AND s.rowid NOT IN (" . $this->db->sanitize(implode(',
', $excludeids)) . ")";
2169 // Add where from hooks
2170 $parameters = array();
2171 $reshook = $hookmanager->executeHooks('selectThirdpartyListWhere
', $parameters); // Note that $action and $object may have been modified by hook
2172 $sql .= $hookmanager->resPrint;
2174 if ($filterkey && $filterkey != '') {
2176 $prefix = !getDolGlobalString('COMPANY_DONOTSEARCH_ANYWHERE
') ? '%
' : ''; // Can use index if COMPANY_DONOTSEARCH_ANYWHERE is on
2177 // For natural search
2178 $search_crit = explode(' ', $filterkey);
2180 if (count($search_crit) > 1) {
2183 foreach ($search_crit as $crit) {
2187 $sql .= "(s.nom LIKE '" . $this->db->escape($prefix . $crit) . "%
')";
2190 if (count($search_crit) > 1) {
2193 if (isModEnabled('barcode
')) {
2194 $sql .= " OR s.barcode LIKE '" . $this->db->escape($prefix . $filterkey) . "%
'";
2196 $sql .= " OR s.code_client LIKE '" . $this->db->escape($prefix . $filterkey) . "%
' OR s.code_fournisseur LIKE '" . $this->db->escape($prefix . $filterkey) . "%
'";
2197 $sql .= " OR s.name_alias LIKE '" . $this->db->escape($prefix . $filterkey) . "%
' OR s.tva_intra LIKE '" . $this->db->escape($prefix . $filterkey) . "%
'";
2200 $sql .= $this->db->order("nom", "ASC");
2201 $sql .= $this->db->plimit($limit, 0);
2203 // Build output string
2204 dol_syslog(get_class($this)."::select_thirdparty_list", LOG_DEBUG);
2205 $resql = $this->db->query($sql);
2207 // Construct $out and $outarray
2208 $out .= '<select
id=
"' . $htmlname . '" class=
"flat' . ($morecss ? ' ' . $morecss : '') . '"' . ($moreparam ? ' ' . $moreparam : '') . ' name=
"' . $htmlname . ($multiple ? '[]' : '') . '"' . ($multiple ? ' multiple
' : '') . '>
' . "\n";
2210 $textifempty = (($showempty && !is_numeric($showempty)) ? $langs->trans($showempty) : '');
2211 if (getDolGlobalString('COMPANY_USE_SEARCH_TO_SELECT
')) {
2212 // Do not use textifempty = ' ' or '
' here, or search on key will search on ' key
'.
2213 //if (!empty($conf->use_javascript_ajax) || $forcecombo) $textifempty='';
2214 if ($showempty && !is_numeric($showempty)) {
2215 $textifempty = $langs->trans($showempty);
2217 $textifempty .= $langs->trans("All");
2221 $out .= '<option value=
"-1" data-html=
"' . dol_escape_htmltag('<span class="opacitymedium
">' . ($textifempty ? $textifempty : ' ') . '</span>') . '">
' . $textifempty . '</option>
' . "\n";
2224 $companytemp = new Societe($this->db);
2226 $num = $this->db->num_rows($resql);
2230 $obj = $this->db->fetch_object($resql);
2232 if ($showcode || getDolGlobalString('SOCIETE_ADD_REF_IN_LIST
')) {
2233 if (($obj->client) && (!empty($obj->code_client))) {
2234 $label = $obj->code_client . ' -
';
2236 if (($obj->fournisseur) && (!empty($obj->code_fournisseur))) {
2237 $label .= $obj->code_fournisseur . ' -
';
2239 $label .= ' ' . $obj->name;
2241 $label = $obj->name;
2244 if (!empty($obj->name_alias)) {
2245 $label .= ' (
' . $obj->name_alias . ')
';
2248 if (getDolGlobalString('SOCIETE_SHOW_VAT_IN_LIST
') && !empty($obj->tva_intra)) {
2249 $label .= ' -
'.$obj->tva_intra;
2252 $labelhtml = $label;
2255 $companytemp->id = $obj->rowid;
2256 $companytemp->client = $obj->client;
2257 $companytemp->fournisseur = $obj->fournisseur;
2258 $tmptype = $companytemp->getTypeUrl(1, '', 0, 'span
');
2260 $labelhtml .= ' ' . $tmptype;
2263 if ($obj->client || $obj->fournisseur) {
2266 if ($obj->client == 1 || $obj->client == 3) {
2267 $label .= $langs->trans("Customer");
2269 if ($obj->client == 2 || $obj->client == 3) {
2270 $label .= ($obj->client == 3 ? ',
' : '') . $langs->trans("Prospect");
2272 if ($obj->fournisseur) {
2273 $label .= ($obj->client ? ',
' : '') . $langs->trans("Supplier");
2275 if ($obj->client || $obj->fournisseur) {
2280 if (getDolGlobalString('COMPANY_SHOW_ADDRESS_SELECTLIST
')) {
2281 $s = ($obj->address ? ' -
' . $obj->address : '') . ($obj->zip ? ' -
' . $obj->zip : '') . ($obj->town ? ' ' . $obj->town : '');
2282 if (!empty($obj->country_code)) {
2283 $s .= ',
' . $langs->trans('Country
' . $obj->country_code);
2289 if (empty($outputmode)) {
2290 if (in_array($obj->rowid, $selected)) {
2291 $out .= '<option value=
"' . $obj->rowid . '" selected data-html=
"' . dol_escape_htmltag($labelhtml, 0, 0, '', 0, 1) . '">
' . dol_escape_htmltag($label, 0, 0, '', 0, 1) . '</option>
';
2293 $out .= '<option value=
"' . $obj->rowid . '" data-html=
"' . dol_escape_htmltag($labelhtml, 0, 0, '', 0, 1) . '">
' . dol_escape_htmltag($label, 0, 0, '', 0, 1) . '</option>
';
2296 array_push($outarray, array('key
' => $obj->rowid, 'value
' => $label, 'label
' => $label, 'labelhtml
' => $labelhtml));
2300 if (($i % 10) == 0) {
2305 $out .= '</select>
' . "\n";
2307 include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php
';
2308 $out .= ajax_combobox($htmlname, $events, getDolGlobalInt("COMPANY_USE_SEARCH_TO_SELECT"));
2311 dol_print_error($this->db);
2314 $this->result = array('nbofthirdparties
' => $num);
2350 public function selectcontacts($socid, $selected = array(), $htmlname = 'contactid
', $showempty = 0, $exclude = '', $limitto = '', $showfunction = 0, $morecss = '', $options_only = 0, $showsoc = 0, $forcecombo = 0, $events = array(), $moreparam = '', $htmlid = '', $multiple = false, $disableifempty = 0, $filter = '', $limit = 0, $limitoffset = 0)
2352 global $conf, $user, $langs, $hookmanager, $action;
2354 $langs->load('companies
');
2356 if (empty($htmlid)) {
2357 $htmlid = $htmlname;
2361 $outarray = array();
2363 if ($selected === '') {
2364 $selected = array();
2365 } elseif (!is_array($selected)) {
2366 $selected = array((int) $selected);
2369 // Clean $filter that may contains sql conditions so sql code
2371 if (testSqlAndScriptInject($filter, 3) > 0) {
2373 return 'SQLInjectionTryDetected
';
2377 if ($filter != '') { // If a filter was provided
2378 if (preg_match('/[\(\)]/
', $filter)) {
2379 // If there is one parenthesis inside the criteria, we assume it is an Universal Filter Syntax.
2381 $filter = forgeSQLFromUniversalSearchCriteria($filter, $errormsg, 1);
2383 // Redo clean $filter that may contains sql conditions so sql code
2385 if (testSqlAndScriptInject($filter, 3) > 0) {
2387 return 'SQLInjectionTryDetected
';
2391 // If not, we do nothing. We already know that there is no parenthesis
2392 // TODO Disallow this case in a future by returning an error here.
2393 dol_syslog("Warning, select_thirdparty_list was called with a filter criteria not using the Universal Search Filter Syntax.", LOG_WARNING);
2397 if (!is_object($hookmanager)) {
2398 include_once DOL_DOCUMENT_ROOT . '/core/
class/hookmanager.class.php
';
2399 $hookmanager = new HookManager($this->db);
2402 // We search third parties
2403 $sql = "SELECT sp.rowid, sp.lastname, sp.statut, sp.firstname, sp.poste, sp.email, sp.phone, sp.phone_perso, sp.phone_mobile, sp.town AS contact_town";
2404 if ($showsoc > 0 || getDolGlobalString('CONTACT_SHOW_EMAIL_PHONE_TOWN_SELECTLIST
')) {
2405 $sql .= ", s.nom as company, s.town AS company_town";
2407 $sql .= " FROM " . $this->db->prefix() . "socpeople as sp";
2408 if ($showsoc > 0 || getDolGlobalString('CONTACT_SHOW_EMAIL_PHONE_TOWN_SELECTLIST
')) {
2409 $sql .= " LEFT JOIN " . $this->db->prefix() . "societe as s ON s.rowid = sp.fk_soc";
2411 $sql .= " WHERE sp.entity IN (" . getEntity('contact
') . ")";
2412 $sql .= " AND ((sp.fk_user_creat = ".((int) $user->id)." AND sp.priv = 1) OR sp.priv = 0)"; // check if this is a private contact
2413 if ($socid > 0 || $socid == -1) {
2414 $sql .= " AND sp.fk_soc = " . ((int) $socid);
2416 if (getDolGlobalString('CONTACT_HIDE_INACTIVE_IN_COMBOBOX
')) {
2417 $sql .= " AND sp.statut <> 0";
2419 // filter user access
2420 if (!$user->hasRight('societe
', 'client
', 'voir
') && !$user->socid) {
2421 $sql .= " AND EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = sp.fk_soc AND sc.fk_user = ".(int) $user->id .")";
2423 if ($user->socid > 0) {
2424 $sql .= " AND sp.fk_soc = ".((int) $user->socid);
2427 // $filter is safe because, if it contains '(
' or ')
', it has been sanitized by testSqlAndScriptInject() and forgeSQLFromUniversalSearchCriteria()
2428 // if not, by testSqlAndScriptInject() only.
2429 $sanitizedfilter = $filter; // @phan-suppress-current-line SqlInjection
2430 $sql .= " AND (" . $sanitizedfilter . ")";
2432 // Add where from hooks
2433 $parameters = array();
2434 $reshook = $hookmanager->executeHooks('selectContactListWhere
', $parameters); // Note that $action and $object may have been modified by hook
2435 $sql .= $hookmanager->resPrint;
2436 $sql .= " ORDER BY sp.lastname ASC";
2437 $sql .= $this->db->plimit($limit, ((int) $limitoffset > 0 ? (int) $limitoffset : 0));
2439 dol_syslog(get_class($this) . "::selectcontacts", LOG_DEBUG);
2440 $resql = $this->db->query($sql);
2442 $num = $this->db->num_rows($resql);
2444 if ($htmlname != 'none
' && !$options_only) {
2445 $out .= '<select
class=
"flat' . ($morecss ? ' ' . $morecss : '') . '" id=
"' . $htmlid . '" name=
"' . $htmlname . ($multiple ? '[]' : '') . '" ' . (($num || empty($disableifempty)) ? '' : ' disabled') . ($multiple ? 'multiple
' : '') . ' ' . (!empty($moreparam) ? $moreparam : '') . '>
';
2448 if ($showempty && !is_numeric($showempty)) {
2449 $textforempty = $showempty;
2450 $out .= '<option
class=
"optiongrey" value=
"-1"' . (in_array(-1, $selected) ? ' selected
' : '') . '>
' . dol_escape_htmltag($textforempty) . '</option>
';
2452 if (($showempty == 1 || ($showempty == 3 && $num > 1)) && !$multiple) {
2453 $out .= '<option value=
"0"' . (in_array(0, $selected) ? ' selected
' : '') . '> </option>
';
2455 if ($showempty == 2) {
2456 $out .= '<option value=
"0"' . (in_array(0, $selected) ? ' selected
' : '') . '>--
' . $langs->trans("Internal") . ' --</option>
';
2462 include_once DOL_DOCUMENT_ROOT . '/contact/
class/contact.class.php
';
2463 $contactstatic = new Contact($this->db);
2466 $obj = $this->db->fetch_object($resql);
2468 // Set email (or phones) and town extended infos
2469 $extendedInfos = '';
2470 if (getDolGlobalString('CONTACT_SHOW_EMAIL_PHONE_TOWN_SELECTLIST
')) {
2471 $extendedInfos = array();
2472 $email = trim($obj->email);
2473 if (!empty($email)) {
2474 $extendedInfos[] = $email;
2476 $phone = trim($obj->phone);
2477 $phone_perso = trim($obj->phone_perso);
2478 $phone_mobile = trim($obj->phone_mobile);
2479 if (!empty($phone)) {
2480 $extendedInfos[] = $phone;
2482 if (!empty($phone_perso)) {
2483 $extendedInfos[] = $phone_perso;
2485 if (!empty($phone_mobile)) {
2486 $extendedInfos[] = $phone_mobile;
2489 $contact_town = trim($obj->contact_town);
2490 $company_town = trim($obj->company_town);
2491 if (!empty($contact_town)) {
2492 $extendedInfos[] = $contact_town;
2493 } elseif (!empty($company_town)) {
2494 $extendedInfos[] = $company_town;
2496 $extendedInfos = implode(' -
', $extendedInfos);
2497 if (!empty($extendedInfos)) {
2498 $extendedInfos = ' -
' . $extendedInfos;
2502 $contactstatic->id = $obj->rowid;
2503 $contactstatic->lastname = $obj->lastname;
2504 $contactstatic->firstname = $obj->firstname;
2505 if ($obj->statut == 1) {
2507 if ($htmlname != 'none
') {
2509 if (is_array($exclude) && count($exclude) && in_array($obj->rowid, $exclude)) {
2512 if (is_array($limitto) && count($limitto) && !in_array($obj->rowid, $limitto)) {
2515 if (!empty($selected) && in_array($obj->rowid, $selected)) {
2516 $out .= '<option value=
"' . $obj->rowid . '"';
2520 $out .= ' selected>
';
2522 $tmplabel = $contactstatic->getFullName($langs) . $extendedInfos;
2523 if ($showfunction && $obj->poste) {
2524 $tmplabel .= ' (
' . $obj->poste . ')
';
2526 if (($showsoc > 0) && $obj->company) {
2527 $tmplabel .= ' - (
' . $obj->company . ')
';
2531 $out .= '</option>
';
2533 $out .= '<option value=
"' . $obj->rowid . '"';
2539 $tmplabel = $contactstatic->getFullName($langs) . $extendedInfos;
2540 if ($showfunction && $obj->poste) {
2541 $tmplabel .= ' (
' . $obj->poste . ')
';
2543 if (($showsoc > 0) && $obj->company) {
2544 $tmplabel .= ' - (
' . $obj->company . ')
';
2548 $out .= '</option>
';
2551 if (in_array($obj->rowid, $selected)) {
2552 $tmplabel = $contactstatic->getFullName($langs) . $extendedInfos;
2553 if ($showfunction && $obj->poste) {
2554 $tmplabel .= ' (
' . $obj->poste . ')
';
2556 if (($showsoc > 0) && $obj->company) {
2557 $tmplabel .= ' - (
' . $obj->company . ')
';
2564 if ($tmplabel != '') {
2565 array_push($outarray, array('key
' => $obj->rowid, 'value
' => $tmplabel, 'label
' => $tmplabel, 'labelhtml
' => $tmplabel));
2571 $labeltoshow = ($socid != -1) ? ($langs->trans($socid ? "NoContactDefinedForThirdParty" : "NoContactDefined")) : $langs->trans('SelectAThirdPartyFirst
');
2572 $out .= '<option
class=
"disabled" value=
"-1"' . (($showempty == 2 || $multiple) ? '' : ' selected
') . ' disabled=
"disabled">
';
2573 $out .= $labeltoshow;
2574 $out .= '</option>
';
2577 $parameters = array(
2579 'htmlname
' => $htmlname,
2582 'showfunction
' => $showfunction,
2583 'showsoc
' => $showsoc,
2586 $reshook = $hookmanager->executeHooks('afterSelectContactOptions
', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
2588 if ($htmlname != 'none
' && !$options_only) {
2589 $out .= '</select>
';
2592 if ($conf->use_javascript_ajax && !$forcecombo && !$options_only) {
2593 include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php
';
2594 $out .= ajax_combobox($htmlid, $events, getDolGlobalInt("CONTACT_USE_SEARCH_TO_SELECT"));
2599 if ($options_only === 2) {
2600 // Return array of options
2606 dol_print_error($this->db);
2612 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2624 public function select_remises($selected, $htmlname, $filter, $socid, $maxvalue = 0)
2627 global $langs, $conf;
2629 $showsourceinvoice = getDolGlobalString('MAIN_SHOW_FACNUMBER_IN_DISCOUNT_LIST
');
2631 // Search for the discounts
2632 $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,";
2633 $sql .= " re.description, re.fk_facture_source, re.fk_invoice_supplier_source";
2634 if ($showsourceinvoice) {
2635 // Resolve the source invoice (customer or supplier) in the main query instead of one fetch per line
2636 $sql .= ", f.ref as src_cust_ref, f.datef as src_cust_date";
2637 $sql .= ", ff.ref as src_supp_ref, ff.datef as src_supp_date";
2639 $sql .= " FROM " . $this->db->prefix() . "societe_remise_except as re";
2640 if ($showsourceinvoice) {
2641 $sql .= " LEFT JOIN " . $this->db->prefix() . "facture as f ON f.rowid = re.fk_facture_source";
2642 $sql .= " LEFT JOIN " . $this->db->prefix() . "facture_fourn as ff ON ff.rowid = re.fk_invoice_supplier_source";
2644 $sql .= " WHERE re.fk_soc = " . (int) $socid;
2645 $sql .= " AND re.entity = " . ((int) $conf->entity);
2647 $sanitizedfilter = $filter; // @phan-suppress-current-line SqlInjection
2648 if ($showsourceinvoice) {
2649 // The joined tables also carry a fk_facture_source column: qualify unprefixed references of the caller filter
2650 $sanitizedfilter = preg_replace('/(?<![a-zA-Z0-9_.])fk_facture_source\b/
', 're.fk_facture_source
', $sanitizedfilter);
2652 $sql .= " AND " . $sanitizedfilter;
2654 if ($showsourceinvoice) {
2655 // When the source invoices are shown, their date is the natural order (oldest deposit first)
2656 $sql .= " ORDER BY COALESCE(ff.datef, f.datef, re.datec) ASC, re.rowid ASC";
2658 $sql .= " ORDER BY re.description ASC";
2661 dol_syslog(get_class($this) . "::select_remises", LOG_DEBUG);
2662 $resql = $this->db->query($sql);
2664 print '<select
id=
"select_' . $htmlname . '" class=
"flat maxwidth300 maxwidth200onsmartphone" name=
"' . $htmlname . '">
';
2665 $num = $this->db->num_rows($resql);
2667 $qualifiedlines = $num;
2671 print '<option value=
"0"> </option>
';
2673 $obj = $this->db->fetch_object($resql);
2674 $desc = dol_trunc($obj->description, 40);
2675 if (preg_match('/\(CREDIT_NOTE\)/
', $desc)) {
2676 $desc = preg_replace('/\(CREDIT_NOTE\)/
', $langs->trans("CreditNote"), $desc);
2678 if (preg_match('/\(DEPOSIT\)/
', $desc)) {
2679 $desc = preg_replace('/\(DEPOSIT\)/
', $langs->trans("Deposit"), $desc);
2681 if (preg_match('/\(EXCESS RECEIVED\)/
', $desc)) {
2682 $desc = preg_replace('/\(EXCESS RECEIVED\)/
', $langs->trans("ExcessReceived"), $desc);
2684 if (preg_match('/\(EXCESS PAID\)/
', $desc)) {
2685 $desc = preg_replace('/\(EXCESS PAID\)/
', $langs->trans("ExcessPaid"), $desc);
2689 if ($selected > 0 && $selected == $obj->rowid) {
2690 $selectstring = ' selected
';
2694 if ($maxvalue > 0 && $obj->amount_ttc > $maxvalue) {
2699 if ($showsourceinvoice) {
2700 $srcref = !empty($obj->src_supp_ref) ? $obj->src_supp_ref : (!empty($obj->src_cust_ref) ? $obj->src_cust_ref : '');
2701 $srcdate = !empty($obj->src_supp_date) ? $obj->src_supp_date : (!empty($obj->src_cust_date) ? $obj->src_cust_date : '');
2703 $desc = $desc . ' -
' . $srcref;
2705 $desc .= ' (
' . dol_print_date($this->db->jdate($srcdate), 'day
') . ')
';
2710 print '<option value=
"' . $obj->rowid . '"' . $selectstring . $disabled . '>
' . $desc . ' (
' . price($obj->amount_ht) . ' ' . $langs->trans("HT") . ' -
' . price($obj->amount_ttc) . ' ' . $langs->trans("TTC") . ')</option>
';
2715 print ajax_combobox('select_
' . $htmlname);
2717 return $qualifiedlines;
2719 dol_print_error($this->db);
2725 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2742 public function select_users($selected = '
', $htmlname = 'userid
', $show_empty = 0, $exclude = null, $disabled = 0, $include = '', $enableonly = array(), $force_entity = '0
')
2745 print $this->select_dolusers($selected, $htmlname, $show_empty, $exclude, $disabled, $include, $enableonly, $force_entity);
2759 public static $user_combo_allowed_morefilters = array(
2760 'u.statut:=:1
', // active users only
2761 '(statut:=:1)
', // active users only
2762 'employee:=:1
', // employees only
2763 '(employee:=:1)
', // employees only
2764 '(admin:=:1) AND (statut:=:1)
', // active administrators only
2774 public static function isUserComboMorefilterAllowed($morefilter)
2776 return in_array(trim((string) $morefilter), self::$user_combo_allowed_morefilters, true);
2794 private function buildSelectDolusersAjaxUrlOption($htmlname, $exclude, $include, $force_entity, $showstatus, $notdisabled, $maxlength, $morefilter = '
')
2796 $urloption = 'htmlname=
'.urlencode($htmlname).'&outjson=1
';
2797 if (is_array($exclude) && count($exclude)) {
2798 $urloption .= '&exclude=
'.urlencode(implode(',
', $exclude));
2800 if (is_array($include) && count($include)) {
2801 $urloption .= '&include=
'.urlencode(implode(',
', $include));
2802 } elseif (is_string($include) && $include !== '') {
2803 $urloption .= '&include=
'.urlencode($include);
2805 if ($force_entity !== '') {
2806 $urloption .= '&force_entity=
'.urlencode((string) $force_entity);
2808 if ($showstatus !== 0) {
2809 $urloption .= '&showstatus=
'.((int) $showstatus);
2811 if (!empty($notdisabled)) {
2812 $urloption .= '¬disabled=1
';
2814 if (!empty($maxlength)) {
2815 $urloption .= '&maxlength=
'.((int) $maxlength);
2817 // $morefilter is a raw Universal Search Filter fed to forgeSQLFromUniversalSearchCriteria().
2818 // Only forward it when it is one of the known-safe expressions of self::$user_combo_allowed_morefilters
2819 // (the endpoint re-checks against the same list); any other value would let a client run arbitrary
2820 // WHERE clauses on llx_user and is dropped here - the ajax list is then simply not narrowed by it.
2821 if ((string) $morefilter !== '') {
2822 if (self::isUserComboMorefilterAllowed($morefilter)) {
2823 $urloption .= '&morefilter=
'.urlencode(trim((string) $morefilter));
2825 dol_syslog(__METHOD__.": morefilter '".$morefilter."' is not in Form::\$user_combo_allowed_morefilters; the search-to-select user list will not be narrowed by it", LOG_WARNING);
2842 private function buildSelectDolusersAjaxSelect2Script($htmlname, $urloption, $minlengthforajax, $ajaxpagesize)
2844 $htmlnamejs = str_replace('.
', '\\\\.
', $htmlname);
2845 return '<script nonce=
"'.getNonce().'">jQuery(function() {
2846 jQuery(
"#'.$htmlnamejs.'").select2({
2848 language: (typeof select2arrayoflanguage ===
"undefined") ?
"en" : select2arrayoflanguage,
2849 containerCssClass:
":all:",
2851 minimumInputLength:
'.((int) $minlengthforajax).',
2853 url:
"'.DOL_URL_ROOT.'/user/ajax/users.php?'.$urloption.'",
2856 data:
function(params) {
2858 d[
'.json_encode($htmlname).'] = params.term;
2859 d.page = params.page || 1;
2862 processResults:
function(data) {
2864 jQuery.each(data,
function(i, val) {
2865 result.push({ id: val.key, text: val.value });
2867 return { results: result, pagination: { more: data.length >=
'.((int) $ajaxpagesize).' } };
2875 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2904 public function select_dolusers($userselected = '
', $htmlname = 'userid
', $show_empty = 0, $exclude = null, $disabled = 0, $include = '', $enableonly = '', $force_entity = '', $maxlength = 0, $showstatus = 0, $morefilter = '', $showalso = 0, $enableonlytext = '', $morecss = '', $notdisabled = 0, $outputmode = 0, $multiple = false, $forcecombo = 0, $filterkey = '', $limit = 0, $limitoffset = 0)
2907 global $conf, $user, $langs, $hookmanager;
2910 // Convert $selected into an int (in case it is an object)
2911 if (is_object($userselected)) {
2912 $selected = (int) $userselected->id;
2913 } elseif (is_numeric($userselected)) {
2914 $selected = (int) $userselected;
2915 } elseif (is_array($userselected)) {
2916 $selected = $userselected;
2921 // If no preselected user defined, we take current user
2922 if ((is_numeric($selected) && ((int) $selected < -4 || empty($selected))) && !getDolGlobalString('SOCIETE_DISABLE_DEFAULT_SALESREPRESENTATIVE
')) {
2923 $selected = $user->id;
2926 // Convert selected int into an array
2927 if (!is_array($selected)) {
2928 if ($selected === -1 || $selected === '') {
2929 $selected = array();
2931 $selected = array($selected);
2935 // Exclude some users in $excludeUsers string
2936 $excludeUsers = null;
2937 if (is_array($exclude)) {
2938 $excludeUsers = implode(",", $exclude);
2941 // Include some users in $includeUsers string
2942 $includeUsers = null;
2943 $includeUsersArray = array();
2944 if (is_array($include)) {
2945 $includeUsersArray = $include;
2946 } elseif ($include == 'hierarchy
') {
2947 // Build list includeUsersArray to have only hierarchy
2948 $includeUsersArray = $user->getAllChildIds(0);
2949 } elseif ($include == 'hierarchyme
') {
2950 // Build list includeUsersArray to have only hierarchy and current user
2951 $includeUsersArray = $user->getAllChildIds(1);
2953 // Get list of allowed users
2954 /* We do not limit list of users. Because we should limit this only for combo list into HR features where we may be allowed to
2955 * see all other users and element in other. For example in agenda, we can have permission to read all event of otherusers.
2956 * So we disable this.
2957 if (!$user->hasRight('user', 'user', 'lire
')) {
2958 if (empty($includeUsersArray)) {
2959 $includeUsers = implode(",", $user->getAllChildIds(1));
2961 $includeUsers = implode(",", array_intersect($includeUsersArray, $user->getAllChildIds(1)));
2964 $includeUsers = implode(",", $includeUsersArray);
2966 $includeUsers = implode(",", $includeUsersArray);
2971 $outarray = array();
2972 $outarray2 = array();
2974 // If the ajax "search to select" mode is enabled for users (constant USER_USE_SEARCH_TO_SELECT), we output a
2975 // select2 combo calling user/ajax/users.php instead of loading the full list of users. This is limited to
2976 // the HTML output: array output, forced combo, pseudo-entries (showalso) and per-line enabling (enableonly)
2977 // keep the full-list behaviour. Both single and multiple select page through the same endpoint (see
2978 // buildSelectDolusersAjaxSelect2Script()); only the <select> markup (single option vs multiple/[]) differs.
2979 $canajaxsearchtoselect = !empty($conf->use_javascript_ajax) && getDolGlobalString('USER_USE_SEARCH_TO_SELECT
') && !$forcecombo && empty($outputmode)
2980 && empty($showalso) && !(is_array($enableonly) && count($enableonly)) && $filterkey === '';
2982 if ($canajaxsearchtoselect && !$multiple) {
2984 if (!empty($selected)) {
2985 $firstval = reset($selected);
2986 if (is_numeric($firstval) && (int) $firstval > 0) {
2987 $preselected = (int) $firstval;
2991 $preselectedlabel = '';
2992 if ($preselected > 0) {
2993 $usertmpselect = new User($this->db);
2994 if ($usertmpselect->fetch($preselected) > 0) {
2995 $fullNameMode = getDolGlobalString('MAIN_FIRSTNAME_NAME_POSITION
') ? 0 : 1;
2996 $preselectedlabel = $usertmpselect->getFullName($langs, $fullNameMode, -1, $maxlength);
2997 if ($preselectedlabel === '') {
2998 $preselectedlabel = $usertmpselect->login;
3001 unset($usertmpselect);
3004 $out .= '<select
class=
"flat'.($morecss ? ' '.$morecss : ' minwidth200').'" id=
"'.$htmlname.'" name=
"'.$htmlname.'"'.($disabled ? ' disabled' : '').'>
';
3005 if ($preselected > 0) {
3006 $out .= '<option value=
"'.$preselected.'" selected>
'.dol_escape_htmltag($preselectedlabel).'</option>
';
3008 $out .= '</select>
';
3010 // Propagate the filters to the ajax endpoint so it returns the same subset as the full combo would
3011 $urloption = $this->buildSelectDolusersAjaxUrlOption($htmlname, $exclude, $include, $force_entity, $showstatus, $notdisabled, $maxlength, $morefilter);
3013 // A non-numeric value ('infinite
') means "infinite list": no minimum number of chars, the list
3014 // opens as soon as the field gets the focus (select2 queries the endpoint with an empty term).
3015 $minlengthforajax = getDolGlobalInt('USER_USE_SEARCH_TO_SELECT
');
3016 if ($minlengthforajax < 1) {
3017 $minlengthforajax = 0;
3019 // Page size of the ajax endpoint (USER_LIMIT_SIZE): select2 keeps asking for the next page
3020 // while the endpoint returns a full page, so the whole list stays browsable by scrolling.
3021 $ajaxpagesize = getDolGlobalInt('USER_LIMIT_SIZE
', 20);
3023 $out .= $this->buildSelectDolusersAjaxSelect2Script($htmlname, $urloption, $minlengthforajax, $ajaxpagesize);
3024 $out .= '<!-- force css to be higher than dialog popup --><style
type=
"text/css">.select2-container { z-index: 1010; }</style>
';
3029 if ($canajaxsearchtoselect && $multiple) {
3030 // Multiple select + "search to select": render a select2 combo pre-filled with only the currently
3031 // selected users as <option selected>. select2 keeps those and fetches the rest on demand from
3032 // user/ajax/users.php instead of loading the whole llx_user table into the page.
3033 $preselectedids = array();
3034 foreach ($selected as $tmpid) {
3035 if (is_numeric($tmpid) && (int) $tmpid > 0) {
3036 $preselectedids[] = (int) $tmpid;
3040 $fullNameMode = getDolGlobalString('MAIN_FIRSTNAME_NAME_POSITION
') ? 0 : 1;
3041 $out .= '<select
class=
"flat'.($morecss ? ' '.$morecss : ' minwidth200').'" id=
"'.$htmlname.'" name=
"'.$htmlname.'[]" multiple
'.($disabled ? ' disabled' : '').'>
';
3042 if (count($preselectedids)) {
3043 $usertmpselect = new User($this->db);
3044 foreach ($preselectedids as $tmpid) {
3045 if ($usertmpselect->fetch($tmpid) > 0) {
3046 $labeltoshow = $usertmpselect->getFullName($langs, $fullNameMode, -1, $maxlength);
3047 if ($labeltoshow === '') {
3048 $labeltoshow = $usertmpselect->login;
3050 $out .= '<option value=
"'.$tmpid.'" selected>
'.dol_escape_htmltag($labeltoshow).'</option>
';
3053 unset($usertmpselect);
3055 $out .= '</select>
';
3057 $urloption = $this->buildSelectDolusersAjaxUrlOption($htmlname, $exclude, $include, $force_entity, $showstatus, $notdisabled, $maxlength, $morefilter);
3059 // A non-numeric value ('infinite
') means "infinite list": no minimum number of chars, the list
3060 // opens as soon as the field gets the focus (select2 queries the endpoint with an empty term).
3061 $minlengthforajax = getDolGlobalInt('USER_USE_SEARCH_TO_SELECT
');
3062 if ($minlengthforajax < 1) {
3063 $minlengthforajax = 0;
3065 // Page size of the ajax endpoint (USER_LIMIT_SIZE): select2 keeps asking for the next page
3066 // while the endpoint returns a full page, so the whole list stays browsable by scrolling.
3067 $ajaxpagesize = getDolGlobalInt('USER_LIMIT_SIZE
', 20);
3069 $out .= $this->buildSelectDolusersAjaxSelect2Script($htmlname, $urloption, $minlengthforajax, $ajaxpagesize);
3070 $out .= '<!-- force css to be higher than dialog popup --><style
type=
"text/css">.select2-container { z-index: 1010; }</style>
';
3075 // Do we want to show the label of entity into the combo list ?
3076 $showlabelofentity = isModEnabled('multicompany
') && !getDolGlobalInt('MULTICOMPANY_TRANSVERSE_MODE
') && $conf->entity == 1 && !empty($user->admin) && empty($user->entity) && !preg_match('/^search_/
', $htmlname);
3077 $userissuperadminentityone = isModEnabled('multicompany
') && $conf->entity == 1 && $user->admin && empty($user->entity);
3079 // Forge request to select users
3080 $sql = "SELECT DISTINCT u.rowid, u.lastname as lastname, u.firstname, u.statut as status, u.login, u.admin, u.entity, u.gender, u.photo";
3081 if ($showlabelofentity) {
3082 $sql .= ", e.label";
3084 $sql .= " FROM " . $this->db->prefix() . "user as u";
3085 if ($showlabelofentity) {
3086 $sql .= " LEFT JOIN " . $this->db->prefix() . "entity as e ON e.rowid = u.entity";
3088 // Condition here should be the same than into societe->getSalesRepresentatives().
3089 if ($userissuperadminentityone && $force_entity !== 'default') {
3090 if (!empty($force_entity)) {
3091 $sql .= " WHERE u.entity IN (0, " . $this->db->sanitize($force_entity) . ")";
3093 $sql .= " WHERE u.entity IS NOT NULL";
3096 if (isModEnabled('multicompany
') && getDolGlobalInt('MULTICOMPANY_TRANSVERSE_MODE
')) {
3097 $sql .= " WHERE u.rowid IN (SELECT ug.fk_user FROM ".$this->db->prefix()."usergroup_user as ug WHERE ug.entity IN (".getEntity('usergroup
')."))";
3099 $sql .= " WHERE u.entity IN (" . getEntity('user') . ")";
3103 if (!empty($user->socid)) {
3104 $sql .= " AND u.fk_soc = " . ((int) $user->socid);
3106 if (is_array($exclude) && $excludeUsers) {
3107 $sql .= " AND u.rowid NOT IN (" . $this->db->sanitize($excludeUsers) . ")";
3109 if ($includeUsers) {
3110 $sql .= " AND u.rowid IN (" . $this->db->sanitize($includeUsers) . ")";
3112 if (getDolGlobalString('USER_HIDE_INACTIVE_IN_COMBOBOX
') || $notdisabled) {
3113 $sql .= " AND (u.statut <> 0";
3114 if (!empty($selected)) {
3115 $sql .= " OR u.rowid IN (".$this->db->sanitize(implode(',
', $selected)).")"; // We must always keep the selected users to avoid to loose it/them when updating
3119 if (getDolGlobalString('USER_HIDE_NONEMPLOYEE_IN_COMBOBOX
')) {
3120 $sql .= " AND u.employee <> 0";
3122 if (getDolGlobalString('USER_HIDE_EXTERNAL_IN_COMBOBOX
')) {
3123 $sql .= " AND u.fk_soc IS NULL";
3125 if (!empty($morefilter)) {
3127 $sql .= forgeSQLFromUniversalSearchCriteria($morefilter, $errormessage);
3128 if ($errormessage) {
3129 $this->errors[] = $errormessage;
3130 dol_syslog(__METHOD__.' '.implode(',
', $this->errors), LOG_ERR);
3131 if ($outputmode == 0) {
3132 return 'Error bad param $morefilter
';
3139 //Add hook to filter on user (for example on usergroup define in custom modules)
3140 $reshook = $hookmanager->executeHooks('addSQLWhereFilterOnSelectUsers
', array(), $this, $action);
3141 if (!empty($reshook)) {
3142 $sql .= $hookmanager->resPrint;
3145 // Add criteria on the natural search string (used by the user/ajax/users.php autocomplete endpoint)
3146 if ($filterkey !== '') {
3148 $prefix = getDolGlobalString('USER_DONOTSEARCH_ANYWHERE
') ? '' : '%
'; // Can use index if USER_DONOTSEARCH_ANYWHERE is on
3149 // For natural search
3150 $search_crit = explode(' ', $filterkey);
3152 if (count($search_crit) > 1) {
3155 foreach ($search_crit as $crit) {
3159 $sql .= "(u.firstname LIKE '".$this->db->escape($prefix.$crit)."%
' OR u.lastname LIKE '".$this->db->escape($prefix.$crit)."%
' OR u.login LIKE '".$this->db->escape($prefix.$crit)."%
')";
3162 if (count($search_crit) > 1) {
3168 if (!getDolGlobalString('MAIN_FIRSTNAME_NAME_POSITION
')) { // MAIN_FIRSTNAME_NAME_POSITION is 0 means firstname+lastname
3169 $sql .= " ORDER BY u.statut DESC, u.firstname ASC, u.lastname ASC";
3171 $sql .= " ORDER BY u.statut DESC, u.lastname ASC, u.firstname ASC";
3175 $sql .= $this->db->plimit($limit, ((int) $limitoffset > 0 ? (int) $limitoffset : 0));
3178 dol_syslog(get_class($this) . "::select_dolusers", LOG_DEBUG);
3180 $resql = $this->db->query($sql);
3182 $num = $this->db->num_rows($resql);
3185 // do not use maxwidthonsmartphone by default. Set it by caller so auto size to 100% will work when not defined
3186 $out .= '<select
class=
"flat' . ($morecss ? ' ' . $morecss : ' minwidth200') . '" id=
"' . $htmlname . '" name=
"' . $htmlname . ($multiple ? '[]' : '') . '" ' . ($multiple ? 'multiple
' : '') . ' ' . ($disabled ? ' disabled' : '') . '>
';
3187 if ($show_empty && !$multiple) {
3188 $textforempty = ' ';
3189 if (!empty($conf->use_javascript_ajax)) {
3190 $textforempty = '
'; // If we use ajaxcombo, we need here to avoid to have an empty element that is too small.
3192 if (!is_numeric($show_empty)) {
3193 $textforempty = $show_empty;
3195 $out .= '<option
class=
"optiongrey" value=
"' . ($show_empty < 0 ? $show_empty : -1) . '"' . ((empty($selected) || in_array(-1, $selected)) ? ' selected
' : '') . '>
' . dol_escape_htmltag($textforempty) . '</option>
' . "\n";
3197 $outarray[($show_empty < 0 ? $show_empty : -1)] = $textforempty;
3198 $outarray2[($show_empty < 0 ? $show_empty : -1)] = array(
3199 'id' => ($show_empty < 0 ? $show_empty : -1),
3200 'label
' => $textforempty,
3201 'labelhtml
' => $textforempty,
3206 if ($showalso == 2 || $showalso == 3) {
3207 $out .= '<option value=
"-3"' . ((in_array(-3, $selected)) ? ' selected
' : '') . '>--
' . $langs->trans("MyTeam") . ' --</option>
' . "\n";
3209 $hasAtLeastOneSubordinate = (count($user->getAllChildIds(1)) > 1);
3210 if ($hasAtLeastOneSubordinate) {
3211 //$sql = "SELECT rowid FROM".MAIN_DB_PREFIX."user "
3212 $outarray[-3] = '--
' . $langs->trans("MyTeam") . ' --
';
3213 $outarray2[-3] = array(
3215 'label
' => '--
' . $langs->trans("MyTeam") . ' --
',
3216 'labelhtml
' => '--
' . $langs->trans("MyTeam") . ' --
',
3222 if ($showalso == 1 || $showalso == 3) {
3223 $out .= '<option value=
"-2"' . ((in_array(-2, $selected)) ? ' selected
' : '') . '>--
' . $langs->trans("Everybody") . ' --</option>
' . "\n";
3225 $outarray[-2] = '--
' . $langs->trans("Everybody") . ' --
';
3226 $outarray2[-2] = array(
3228 'label
' => '--
' . $langs->trans("Everybody") . ' --
',
3229 'labelhtml
' => '--
' . $langs->trans("Everybody") . ' --
',
3234 if ($showalso == 4) {
3235 $out .= '<option value=
"-4"' . ((in_array(-4, $selected)) ? ' selected
' : '') . '>--
' . $langs->trans("AllProjectContacts") . ' --</option>
' . "\n";
3237 $outarray[-4] = '--
' . $langs->trans("AllProjectContacts") . ' --
';
3238 $outarray2[-4] = array(
3240 'label
' => '--
' . $langs->trans("AllProjectContacts") . ' --
',
3241 'labelhtml
' => '--
' . $langs->trans("AllProjectContacts") . ' --
',
3247 $userstatic = new User($this->db);
3250 $obj = $this->db->fetch_object($resql);
3252 $userstatic->id = $obj->rowid;
3253 $userstatic->lastname = $obj->lastname;
3254 $userstatic->firstname = $obj->firstname;
3255 $userstatic->photo = $obj->photo;
3256 $userstatic->status = $obj->status;
3257 $userstatic->entity = $obj->entity;
3258 $userstatic->admin = $obj->admin;
3259 $userstatic->gender = $obj->gender;
3262 if (is_array($enableonly) && count($enableonly) && !in_array($obj->rowid, $enableonly)) {
3263 $disableline = ($enableonlytext ? $enableonlytext : '1
');
3267 $labeltoshowhtml = '';
3269 // $fullNameMode is 0=Lastname+Firstname (MAIN_FIRSTNAME_NAME_POSITION=1), 1=Firstname+Lastname (MAIN_FIRSTNAME_NAME_POSITION=0)
3271 if (!getDolGlobalString('MAIN_FIRSTNAME_NAME_POSITION
')) {
3272 $fullNameMode = 1; //Firstname+lastname
3274 $labeltoshow .= $userstatic->getFullName($langs, $fullNameMode, -1, $maxlength);
3275 $labeltoshowhtml .= $userstatic->getFullName($langs, $fullNameMode, -1, $maxlength);
3276 if (empty($obj->firstname) && empty($obj->lastname)) {
3277 $labeltoshow .= $obj->login;
3278 $labeltoshowhtml .= $obj->login;
3281 // Complete name with a more info string like: ' (info1 - info2 - ...)
'
3284 if (getDolGlobalString('MAIN_SHOW_LOGIN
')) {
3285 $moreinfo .= ($moreinfo ? ' -
' : ' (
');
3286 $moreinfohtml .= ($moreinfohtml ? ' -
' : ' <span
class=
"opacitymedium">(
');
3287 $moreinfo .= $obj->login;
3288 $moreinfohtml .= $obj->login;
3290 if ($showstatus >= 0) {
3291 if ($obj->status == 1 && $showstatus == 1) {
3292 $moreinfo .= ($moreinfo ? ' -
' : ' (
') . $langs->trans('Enabled
');
3293 $moreinfohtml .= ($moreinfohtml ? ' -
' : ' <span
class=
"opacitymedium">(
') . $langs->trans('Enabled
');
3295 if ($obj->status == 0 && $showstatus == 1) {
3296 $moreinfo .= ($moreinfo ? ' -
' : ' (
') . $langs->trans('Disabled
');
3297 $moreinfohtml .= ($moreinfohtml ? ' -
' : ' <span
class=
"opacitymedium">(
') . $langs->trans('Disabled
');
3300 if ($showlabelofentity) {
3301 if (empty($obj->entity)) {
3302 $moreinfo .= ($moreinfo ? ' -
' : ' (
') . $langs->trans("AllEntities");
3303 $moreinfohtml .= ($moreinfohtml ? ' -
' : ' <span
class=
"opacitymedium">(
') . $langs->trans("AllEntities");
3305 if ($obj->entity != $conf->entity) {
3306 $moreinfo .= ($moreinfo ? ' -
' : ' (
') . ($obj->label ? $obj->label : $langs->trans("EntityNameNotDefined"));
3307 $moreinfohtml .= ($moreinfohtml ? ' -
' : ' <span
class=
"opacitymedium">(
').($obj->label ? $obj->label : $langs->trans("EntityNameNotDefined"));
3311 $moreinfo .= (!empty($moreinfo) ? ')
' : '');
3312 $moreinfohtml .= (!empty($moreinfohtml) ? ')</span>
' : '');
3313 if (!empty($disableline) && $disableline != '1
') {
3314 // Add text from $enableonlytext parameter
3315 $moreinfo .= ' -
' . $disableline;
3316 $moreinfohtml .= ' -
' . $disableline;
3318 $labeltoshow .= $moreinfo;
3319 $labeltoshowhtml .= $moreinfohtml;
3321 $out .= '<option value=
"' . $obj->rowid . '"';
3322 if (!empty($disableline)) {
3325 if (in_array($obj->rowid, $selected)) {
3326 $out .= ' selected
';
3328 $out .= ' data-html=
"';
3330 $outhtml = $userstatic->getNomUrl(-3, '', 0, 1, 24, 1, 'login', '', 1) . ' ';
3331 if ($showstatus >= 0 && $obj->status == 0) {
3332 $outhtml .= '<strike class="opacitymediumxxx
">';
3334 $outhtml .= $labeltoshowhtml;
3335 if ($showstatus >= 0 && $obj->status == 0) {
3336 $outhtml .= '</strike>';
3338 $labeltoshowhtml = $outhtml;
3340 $out .= dol_escape_htmltag($outhtml);
3342 $out .= $labeltoshow;
3343 $out .= '</option>
';
3345 $outarray[$userstatic->id] = $userstatic->getFullName($langs, $fullNameMode, -1, $maxlength) . $moreinfo;
3346 $outarray2[$userstatic->id] = array(
3347 'id' => $userstatic->id,
3348 'label
' => $labeltoshow,
3349 'labelhtml
' => $labeltoshowhtml,
3357 $out .= '<select
class=
"flat" id=
"' . $htmlname . '" name=
"' . $htmlname . '" disabled>
';
3358 $out .= '<option value=
"">
' . $langs->trans("None") . '</option>
';
3360 $out .= '</select>
';
3362 if ($num && !$forcecombo) {
3363 // Enhance with select2
3364 include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php
';
3365 $out .= ajax_combobox($htmlname);
3368 dol_print_error($this->db);
3373 if ($outputmode == 2) {
3375 } elseif ($outputmode) {
3383 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3407 public function select_dolusers_forevent($action = '
', $htmlname = 'userid
', $show_empty = 0, $exclude = null, $disabled = 0, $include = array(), $enableonly = array(), $force_entity = '0
', $maxlength = 0, $showstatus = 0, $morefilter = '', $showproperties = 0, $listofuserid = array(), $listofcontactid = array(), $listofotherid = array(), $canremoveowner = 1)
3410 global $langs, $user;
3412 $userstatic = new User($this->db);
3415 // The list of selected users is provided by the caller through $listofuserid (owner first).
3416 // Fall back to the legacy global $_SESSION['assignedtouser
'] only when no list is provided
3417 // (comm/action/card.php now scopes that session bucket per event id and no longer feeds this key).
3418 if (!empty($listofuserid)) {
3419 $assignedtouser = $listofuserid;
3420 } elseif (!empty($_SESSION['assignedtouser
'])) {
3421 $assignedtouser = json_decode($_SESSION['assignedtouser
'], true);
3422 if (!is_array($assignedtouser)) {
3423 $assignedtouser = array();
3426 $assignedtouser = array();
3428 $nbassignetouser = count($assignedtouser);
3430 //if ($nbassignetouser && $action != 'view
') $out .= '<br>
';
3431 if ($nbassignetouser) {
3432 $out .= '<ul
class=
"attendees">
';
3436 foreach ($assignedtouser as $key => $value) {
3437 if ($value['id'] == $ownerid) {
3443 $userstatic->fetch($value['id']);
3444 $out .= $userstatic->getNomUrl(-4);
3447 $ownerid = $value['id'];
3448 $out .= ' (
' . $langs->trans("Owner") . ')
';
3450 // Add picto to delete owner/assignee
3451 if ($nbassignetouser > 1 && $action != 'view
') {
3452 $canremoveassignee = 1;
3454 // We are on the owner of the event
3455 if (!$canremoveowner) {
3456 $canremoveassignee = 0;
3458 if (!$user->hasRight('agenda
', 'allactions
', 'create
')) {
3459 $canremoveassignee = 0; // Can't
remove the owner
3464 if ($canremoveassignee) {
3467 $out .=
' <input type="image" style="border: 0px;" src="' . img_picto($langs->trans(
"Remove"),
'delete',
'', 0, 1) .
'" value="' . $userstatic->id .
'" class="noborderfocus removedassigned reposition" id="removedassigned_' . $userstatic->id .
'" name="removedassigned_' . $userstatic->id .
'">';
3471 if ($showproperties) {
3472 if ($ownerid == $value[
'id'] && is_array($listofuserid) && count($listofuserid) && in_array($ownerid, array_keys($listofuserid))) {
3473 $out .=
'<div class="myavailability inline-block">';
3474 $out .=
'<span class="hideonsmartphone"> - ';
3477 $out .=
' <input title="'.$langs->trans(
"Availability").
'" id="transparency" class="paddingrightonly" ' . ($action ==
'view' ?
'disabled' :
'') .
' type="checkbox" name="transparency"' . ($listofuserid[$ownerid][
'transparency'] ?
' checked' :
'') .
'><label for="transparency">' . $langs->trans(
"Busy") .
'</label>';
3487 if ($nbassignetouser) {
3492 if ($action !=
'view') {
3494 $out .=
'<div class="divadduser'.$htmlname.
'">';
3495 $out .=
'<input type="hidden" class="removedassignedhidden" name="removedassigned" value="">';
3496 $out .=
'<script nonce="' .
getNonce() .
'" type="text/javascript">jQuery(document).ready(function () {';
3497 $out .=
'jQuery(".removedassigned").click(function() { jQuery(".removedassignedhidden").val(jQuery(this).val()); });';
3498 $out .=
'jQuery(".assignedtouser").change(function() { console.log(jQuery(".assignedtouser option:selected").val());';
3499 $out .=
' if (jQuery(".assignedtouser option:selected").val() > 0) { jQuery("#' . $action .
'assignedtouser").attr("disabled", false); }';
3500 $out .=
' else { jQuery("#' . $action .
'assignedtouser").attr("disabled", true); }';
3502 $out .=
'})</script>';
3503 $out .= img_picto(
'',
'user',
'class="pictofixedwidth"');
3506 $out .= $this->select_dolusers(
'', $htmlname, $show_empty, $exclude, $disabled, $include, $enableonly, $force_entity, $maxlength, $showstatus, $morefilter, 0,
'',
'minwidth200', 0, 0,
false, 1);
3508 include_once DOL_DOCUMENT_ROOT.
'/core/lib/ajax.lib.php';
3510 $out .=
' <button type="submit" disabled class="button valignmiddle smallpaddingimp reposition butActionAdd" id="' . $action .
'assignedtouser" name="' . $action .
'assignedtouser" value="' .
dol_escape_htmltag($langs->trans(
"Add")) .
'">';
3511 $out .= $langs->trans(
"Add").
'</button>';
3539 public function select_dolresources_forevent($action =
'', $htmlname =
'userid', $show_empty = 0, $exclude =
null, $disabled = 0, $include = array(), $enableonly = array(), $force_entity =
'0', $maxlength = 0, $showstatus = 0, $morefilter =
'', $showproperties = 0, $listofresourceid = array())
3544 require_once DOL_DOCUMENT_ROOT.
'/resource/class/html.formresource.class.php';
3545 require_once DOL_DOCUMENT_ROOT.
'/resource/class/dolresource.class.php';
3550 if (!empty($_SESSION[
'assignedtoresource'])) {
3551 $assignedtoresource = json_decode($_SESSION[
'assignedtoresource'],
true);
3552 if (!is_array($assignedtoresource)) {
3553 $assignedtoresource = array();
3556 $assignedtoresource = array();
3558 $nbassignetoresource = count($assignedtoresource);
3561 if ($nbassignetoresource) {
3562 $out .=
'<ul class="attendees">';
3566 foreach ($assignedtoresource as $key => $value) {
3568 $resourcestatic->fetch($value[
'id']);
3569 $out .= $resourcestatic->getNomUrl(-1);
3570 if ($nbassignetoresource >= 1 && $action !=
'view') {
3571 $out .=
' <input type="image" style="border: 0px;" src="' . img_picto($langs->trans(
"Remove"),
'delete',
'', 0, 1) .
'" value="' . $resourcestatic->id .
'" class="removedassignedresource reposition" id="removedassignedresource_' . $resourcestatic->id .
'" name="removedassignedresource_' . $resourcestatic->id .
'">';
3574 if ($showproperties) {
3575 if (is_array($listofresourceid) && count($listofresourceid)) {
3576 $out .=
'<div class="myavailability inline-block">';
3577 $out .=
'<span class="hideonsmartphone"> - ';
3580 $out .=
' <input title="'.$langs->trans(
"Availability").
'" id="transparencyresource'.$value[
'id'].
'" class="paddingrightonly" ' . ($action ==
'view' ?
'disabled' :
'') .
' type="checkbox" name="transparency"' . ($listofresourceid[$value[
'id']][
'transparency'] ?
' checked' :
'') .
'><label for="transparencyresource'.$value[
'id'].
'">' . $langs->trans(
"Busy") .
'</label>';
3590 if ($nbassignetoresource) {
3595 if ($action !=
'view') {
3596 $out .=
'<input type="hidden" class="removedassignedresourcehidden" name="removedassignedresource" value="">';
3597 $out .=
'<script nonce="' .
getNonce() .
'" type="text/javascript">jQuery(document).ready(function () {';
3598 $out .=
'jQuery(".removedassignedresource").click(function() { jQuery(".removedassignedresourcehidden").val(jQuery(this).val()); });';
3599 $out .=
'jQuery(".assignedtoresource").change(function() { console.log(jQuery(".assignedtoresource option:selected").val());';
3600 $out .=
' if (jQuery(".assignedtoresource option:selected").val() > 0) { jQuery("#' . $action .
'assignedtoresource").attr("disabled", false); }';
3601 $out .=
' else { jQuery("#' . $action .
'assignedtoresource").attr("disabled", true); }';
3603 $out .=
'})</script>';
3606 if ($nbassignetoresource) {
3609 $out .= img_picto(
'',
'resource',
'class="pictofixedwidth"');
3611 $out .= $formresources->select_resource_list(0, $htmlname,
'', 1, 1, 0, $events,
'', 2, 0,
'minwidth200');
3613 $out .=
' <button type="submit" disabled class="button valignmiddle smallpaddingimp reposition butActionAdd" id="' . $action .
'assignedtoresource" name="' . $action .
'assignedtoresource" value="' .
dol_escape_htmltag($langs->trans(
"Add")) .
'">';
3614 $out .= $langs->trans(
"Add");
3615 $out .=
'</button>';
3653 public function select_produits($selected = 0, $htmlname =
'productid', $filtertype =
'', $limit = 0, $price_level = 0, $status = 1, $finished = 2, $selected_input_value =
'', $hidelabel = 0, $ajaxoptions = array(), $socid = 0, $showempty =
'1', $forcecombo = 0, $morecss =
'', $hidepriceinlabel = 0, $warehouseStatus =
'', $selected_combinations =
null, $nooutput = 0, $status_purchase = -1, $warehouseId = 0)
3656 global $langs,
$conf;
3661 $price_level = (!empty($price_level) ? $price_level : 0);
3662 if (is_null($ajaxoptions)) {
3663 $ajaxoptions = array();
3675 $placeholder = (is_numeric($showempty) ?
'' :
'placeholder="'.dolPrintHTML($showempty).
'"');
3677 if ($selected && empty($selected_input_value)) {
3678 require_once DOL_DOCUMENT_ROOT .
'/product/class/product.class.php';
3679 $producttmpselect =
new Product($this->db);
3680 $producttmpselect->fetch($selected);
3681 $selected_input_value = $producttmpselect->ref;
3682 unset($producttmpselect);
3685 if ($filtertype ==
'') {
3693 $urloption = ($socid > 0 ?
'socid=' . $socid .
'&' :
'') .
'htmlname=' . $htmlname .
'&outjson=1&price_level=' . $price_level .
'&type=' . $filtertype .
'&mode=1&status=' . $status .
'&status_purchase=' . $status_purchase .
'&finished=' . $finished .
'&hidepriceinlabel=' . $hidepriceinlabel .
'&warehousestatus=' . $warehouseStatus;
3694 if ((
int) $warehouseId > 0) {
3695 $urloption .=
'&warehouseid=' . (int) $warehouseId;
3698 if (
isModEnabled(
'variants') && is_array($selected_combinations)) {
3704 <!-- script to auto show attributes select tags if a variant was selected -->
3705 <script nonce="' .
getNonce() .
'">
3706 // auto show attributes fields
3707 selected = ' . json_encode($selected_combinations) .
';
3710 jQuery(document).ready(function () {
3712 jQuery("input[name=\'prod_entry_mode\']").change(function () {
3713 if (jQuery(this).val() == \'free\') {
3714 jQuery(\'div#attributes_box\').empty();
3718 jQuery("'.$htmltag.
'#' . $htmlname .
'").change(function () {
3720 if (!jQuery(this).val()) {
3721 jQuery(\'div#attributes_box\').empty();
3725 console.log("A change has started. We get variants fields to inject html select");
3727 jQuery.getJSON("' . DOL_URL_ROOT .
'/variants/ajax/getCombinations.php", {
3728 id: jQuery(this).val()
3729 }, function (data) {
3730 jQuery(\'div#attributes_box\').empty();
3732 jQuery.each(data, function (key, val) {
3734 combvalues[val.id] = val.values;
3736 var span = jQuery(document.createElement(\'div\')).css({
3737 \'display\': \'table-row\'
3741 jQuery(document.createElement(\'div\')).text(val.label).css({
3742 \'font-weight\': \'bold\',
3743 \'display\': \'table-cell\'
3747 var html = jQuery(document.createElement(\'select\')).attr(\'name\', \'combinations[\' + val.id + \']\').css({
3748 \'margin-left\': \'15px\',
3749 \'white-space\': \'pre\'
3751 jQuery(document.createElement(\'option\')).val(\'\')
3754 jQuery.each(combvalues[val.id], function (key, val) {
3755 var tag = jQuery(document.createElement(\'option\')).val(val.id).html(val.value);
3757 if (selected[val.fk_product_attribute] == val.id) {
3758 tag.attr(\'selected\', \'selected\');
3765 jQuery(\'div#attributes_box\').append(span);
3770 ' . ($selected ?
'jQuery("'.$htmltag.
'#' . $htmlname .
'").change();' :
'') .
'
3776 if (empty($hidelabel)) {
3777 $placeholder =
' placeholder="' . dolPrintHTMLForAttribute($langs->trans(
"RefOrLabel")) .
'"';
3778 } elseif ($hidelabel > 1) {
3779 $placeholder =
' placeholder="' . dolPrintHTMLForAttribute($langs->trans(
"RefOrLabel")) .
'"';
3780 if ($hidelabel == 2) {
3781 $out .= img_picto($langs->trans(
"Search"),
'search');
3785 $out .=
'<input type="text" class="minwidth100' . ($morecss ?
' ' . $morecss :
'') .
'" name="search_' . $htmlname .
'" id="search_' . $htmlname .
'" value="' . $selected_input_value .
'"' . $placeholder .
' ' . (
getDolGlobalString(
'PRODUCT_SEARCH_AUTOFOCUS') ?
'autofocus' :
'') .
' spellcheck="false" />';
3786 if ($hidelabel == 3) {
3787 $out .= img_picto($langs->trans(
"Search"),
'search');
3790 $out .=
ajax_autocompleter((
string) $selected, $htmlname, DOL_URL_ROOT .
'/product/ajax/products.php', $urloption,
getDolGlobalInt(
'PRODUIT_USE_SEARCH_TO_SELECT'),
getDolGlobalInt(
'PRODUCT_SEARCH_AUTO_SELECT_IF_ONLY_ONE', 1), $ajaxoptions);
3792 $out .= $this->select_produits_list($selected, $htmlname, $filtertype, $limit, $price_level,
'', $status, $finished, 0, $socid, $showempty, $forcecombo, $morecss, $hidepriceinlabel, $warehouseStatus, $status_purchase, $warehouseId);
3794 if (
isModEnabled(
'variants') && is_array($selected_combinations)) {
3798 $htmltag =
'select';
3800 <!-- script to auto show attributes select tags if a variant was selected -->
3801 <script nonce="' .
getNonce() .
'">
3802 // auto show attributes fields
3803 selected = ' . json_encode($selected_combinations) .
';
3806 jQuery(document).ready(function () {
3808 jQuery("input[name=\'prod_entry_mode\']").change(function () {
3809 if (jQuery(this).val() == \'free\') {
3810 jQuery(\'div#attributes_box\').empty();
3814 jQuery("'.$htmltag.
'#' . $htmlname .
'").change(function () {
3816 if (!jQuery(this).val()) {
3817 jQuery(\'div#attributes_box\').empty();
3821 console.log("A change has started. We get variants fields to inject html select");
3823 jQuery.getJSON("' . DOL_URL_ROOT .
'/variants/ajax/getCombinations.php", {
3824 id: jQuery(this).val()
3825 }, function (data) {
3826 jQuery(\'div#attributes_box\').empty();
3828 jQuery.each(data, function (key, val) {
3830 combvalues[val.id] = val.values;
3832 var span = jQuery(document.createElement(\'div\')).css({
3833 \'display\': \'table-row\'
3837 jQuery(document.createElement(\'div\')).text(val.label).css({
3838 \'font-weight\': \'bold\',
3839 \'display\': \'table-cell\'
3843 var html = jQuery(document.createElement(\'select\')).attr(\'name\', \'combinations[\' + val.id + \']\').css({
3844 \'margin-left\': \'15px\',
3845 \'white-space\': \'pre\'
3847 jQuery(document.createElement(\'option\')).val(\'\')
3850 jQuery.each(combvalues[val.id], function (key, val) {
3851 var tag = jQuery(document.createElement(\'option\')).val(val.id).html(val.value);
3853 if (selected[val.fk_product_attribute] == val.id) {
3854 tag.attr(\'selected\', \'selected\');
3861 jQuery(\'div#attributes_box\').append(span);
3866 ' . ($selected ?
'jQuery("'.$htmltag.
'#' . $htmlname .
'").change();' :
'') .
'
3873 if (empty($nooutput)) {
3897 public function select_bom($selected =
'', $htmlname =
'bom_id', $limit = 0, $status = 1, $type = 0, $showempty =
'1', $morecss =
'', $nooutput =
'', $forcecombo = 0, $TProducts = [])
3901 require_once DOL_DOCUMENT_ROOT .
'/product/class/product.class.php';
3907 include_once DOL_DOCUMENT_ROOT .
'/core/lib/ajax.lib.php';
3912 $out .=
'<select class="flat' . ($morecss ?
' ' . $morecss :
'') .
'" name="' . $htmlname .
'" id="' . $htmlname .
'">';
3914 $sql =
'SELECT b.rowid, b.ref, b.label as bomLabel, p.label as productLabel';
3915 $sql .=
' FROM ' . $this->db->prefix() .
'bom_bom as b';
3916 $sql .=
' INNER JOIN ' . $this->db->prefix() .
'product as p ON b.fk_product = p.rowid';
3917 $sql .=
' WHERE b.entity IN (' .
getEntity(
'bom') .
')';
3918 if (!empty($status)) {
3919 $sql .=
' AND status = ' . (int) $status;
3921 if (!empty($type)) {
3922 $sql .=
' AND bomtype = ' . (int) $type;
3924 if (!empty($TProducts)) {
3925 $sql .=
' AND fk_product IN (' . $this->db->sanitize(implode(
',', $TProducts)) .
')';
3927 if (!empty($limit)) {
3928 $sql .=
' LIMIT ' . (int) $limit;
3930 $resql = $this->db->query($sql);
3933 $out .=
'<option value="-1"';
3934 if (empty($selected)) {
3935 $out .=
' selected';
3937 $out .=
'> </option>';
3939 while ($obj = $this->db->fetch_object($resql)) {
3940 $out .=
'<option value="' . $obj->rowid .
'"';
3941 if ($obj->rowid == $selected) {
3944 $out .=
'>' . $obj->ref .
' - ' . $obj->productLabel .
' - ' . $obj->bomLabel .
'</option>';
3948 dol_print_error($this->db);
3950 $out .=
'</select>';
3951 if (empty($nooutput)) {
3986 public function select_produits_list($selected = 0, $htmlname =
'productid', $filtertype =
'', $limit = 1000, $price_level = 0, $filterkey =
'', $status = 1, $finished = 2, $outputmode = 0, $socid = 0, $showempty =
'1', $forcecombo = 0, $morecss =
'maxwidth500', $hidepriceinlabel = 0, $warehouseStatus =
'', $status_purchase = -1, $warehouseId = 0)
3990 global $hookmanager;
3993 $outarray = array();
3997 $langs->load(
'other');
4000 $warehouseStatusArray = array();
4001 if (!empty($warehouseStatus)) {
4002 require_once DOL_DOCUMENT_ROOT .
'/product/stock/class/entrepot.class.php';
4003 if (preg_match(
'/warehouseclosed/', $warehouseStatus)) {
4006 if (preg_match(
'/warehouseopen/', $warehouseStatus)) {
4009 if (preg_match(
'/warehouseinternal/', $warehouseStatus)) {
4014 $selectFields =
"p.rowid, p.ref, p.label, p.description, p.barcode, p.fk_country, p.fk_product_type, p.price, p.price_ttc, p.price_base_type, p.tva_tx, p.default_vat_code, p.duration, p.fk_price_expression";
4015 if (count($warehouseStatusArray)) {
4016 $selectFieldsGrouped =
", SUM(" . $this->db->ifsql(
"e.statut IS NULL",
"0",
"ps.reel") .
") as stock";
4018 $selectFieldsGrouped =
", " . $this->db->ifsql(
"p.stock IS NULL",
'0',
"p.stock") .
" AS stock";
4024 $parameters = array();
4025 $reshook = $hookmanager->executeHooks(
'selectProductsListSelect', $parameters);
4026 if (empty($reshook)) {
4027 $sql .= $selectFields.$selectFieldsGrouped.$hookmanager->resPrint;
4029 $sql .= $hookmanager->resPrint;
4034 $sql .=
", (SELECT " . $this->db->prefix() .
"categorie_product.fk_categorie
4035 FROM " . $this->db->prefix() .
"categorie_product
4036 WHERE " . $this->db->prefix() .
"categorie_product.fk_product = p.rowid
4038 ) AS categorie_product_id";
4043 $sql .=
', pcp.rowid as idprodcustprice, pcp.price as custprice, pcp.price_ttc as custprice_ttc,';
4044 $sql .=
' pcp.price_base_type as custprice_base_type, pcp.tva_tx as custtva_tx, pcp.default_vat_code as custdefault_vat_code, pcp.ref_customer as custref, pcp.discount_percent as custdiscount_percent';
4045 $selectFields .=
", idprodcustprice, custprice, custprice_ttc, custprice_base_type, custtva_tx, custdefault_vat_code, custref, custdiscount_percent";
4049 $sql .=
", u.label as unit_long, u.short_label as unit_short, p.weight, p.weight_units, p.length, p.length_units, p.width, p.width_units, p.height, p.height_units, p.surface, p.surface_units, p.volume, p.volume_units";
4050 $selectFields .=
', unit_long, unit_short, p.weight, p.weight_units, p.length, p.length_units, p.width, p.width_units, p.height, p.height_units, p.surface, p.surface_units, p.volume, p.volume_units';
4055 $sql .=
", pl.label as label_translated";
4056 $sql .=
", pl.description as description_translated";
4057 $selectFields .=
", label_translated";
4058 $selectFields .=
", description_translated";
4062 $sql .=
", (SELECT pp.rowid FROM " . $this->db->prefix() .
"product_price as pp WHERE pp.fk_product = p.rowid";
4063 if ($price_level >= 1 &&
getDolGlobalString(
'PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES')) {
4064 $sql .=
" AND price_level = " . ((int) $price_level);
4066 $sql .=
" ORDER BY date_price";
4067 $sql .=
" DESC LIMIT 1) as price_rowid";
4068 $sql .=
", (SELECT pp.price_by_qty FROM " . $this->db->prefix() .
"product_price as pp WHERE pp.fk_product = p.rowid";
4069 if ($price_level >= 1 &&
getDolGlobalString(
'PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES')) {
4070 $sql .=
" AND price_level = " . ((int) $price_level);
4072 $sql .=
" ORDER BY date_price";
4073 $sql .=
" DESC LIMIT 1) as price_by_qty";
4074 $selectFields .=
", price_rowid, price_by_qty";
4079 $sql .=
" FROM ".$this->db->prefix().
"product as p";
4082 $sql .=
" USE INDEX (" . $this->db->sanitize(
getDolGlobalString(
'MAIN_PRODUCT_FORCE_INDEX')) .
")";
4086 $parameters = array(
4089 $reshook = $hookmanager->executeHooks(
'selectProductsListFrom', $parameters);
4090 $sql .= $hookmanager->resPrint;
4092 if (count($warehouseStatusArray)) {
4095 $sql .=
" LEFT JOIN " . $this->db->prefix() .
"product_stock as ps ON ps.fk_product = p.rowid";
4096 $sql .=
" LEFT JOIN " . $this->db->prefix() .
"entrepot as e ON ps.fk_entrepot = e.rowid AND e.entity IN (" .
getEntity(
'stock') .
")";
4097 $sql .=
' AND e.statut IN (' . $this->db->sanitize($this->db->escape(implode(
',', $warehouseStatusArray))) .
')';
4103 $sql .=
" LEFT JOIN (";
4104 $sql .=
" SELECT pcp1.*";
4105 $sql .=
" FROM " . $this->db->prefix() .
"product_customer_price AS pcp1";
4106 $sql .=
" LEFT JOIN (";
4107 $sql .=
" SELECT fk_soc, fk_product, MIN(date_begin) AS date_begin";
4108 $sql .=
" FROM " . $this->db->prefix() .
"product_customer_price";
4109 $sql .=
" WHERE fk_soc = " . ((int) $socid);
4110 $sql .=
" AND date_begin <= '" . $this->db->idate($now) .
"'";
4111 $sql .=
" AND (date_end IS NULL OR '" . $this->db->idate($now) .
"' <= date_end)";
4112 $sql .=
" GROUP BY fk_soc, fk_product";
4113 $sql .=
" ) AS pcp2 ON pcp1.fk_soc = pcp2.fk_soc AND pcp1.fk_product = pcp2.fk_product AND pcp1.date_begin = pcp2.date_begin";
4114 $sql .=
" WHERE pcp2.fk_soc IS NOT NULL";
4115 $sql .=
" ) AS pcp ON pcp.fk_soc = " . ((int) $socid) .
" AND pcp.fk_product = p.rowid";
4119 $sql .=
" LEFT JOIN " . $this->db->prefix() .
"c_units as u ON u.rowid = p.fk_unit";
4123 $sql .=
" LEFT JOIN " . $this->db->prefix() .
"product_lang as pl ON pl.fk_product = p.rowid";
4125 require_once DOL_DOCUMENT_ROOT .
'/societe/class/societe.class.php';
4126 $soc =
new Societe($this->db);
4127 $result = $soc->fetch($socid);
4128 if ($result > 0 && !empty($soc->default_lang)) {
4129 $sql .=
" AND pl.lang = '" . $this->db->escape($soc->default_lang) .
"'";
4131 $sql .=
" AND pl.lang = '" . $this->db->escape($langs->getDefaultLang()) .
"'";
4134 $sql .=
" AND pl.lang = '" . $this->db->escape($langs->getDefaultLang()) .
"'";
4139 $sql .=
' WHERE p.entity IN (' .
getEntity(
'product') .
')';
4142 if (strlen($filterkey) != 13) {
4143 $sql .=
" AND NOT EXISTS (SELECT pac.rowid FROM ".$this->db->prefix().
"product_attribute_combination as pac WHERE pac.fk_product_child = p.rowid)";
4146 $sql .=
" AND NOT EXISTS (SELECT pac.rowid FROM ".$this->db->prefix().
"product_attribute_combination as pac WHERE pac.fk_product_child = p.rowid)";
4149 if ($finished == 0) {
4150 $sql .=
" AND p.finished = " . ((int) $finished);
4151 } elseif ($finished == 1) {
4152 $sql .=
" AND p.finished = ".((int) $finished);
4155 $sql .=
" AND p.tosell = ".((int) $status);
4157 if ($status_purchase >= 0) {
4158 $sql .=
" AND p.tobuy = " . ((int) $status_purchase);
4161 if (strval($filtertype) !=
'') {
4162 $sql .=
" AND p.fk_product_type = " . ((int) $filtertype);
4164 $sql .=
" AND p.fk_product_type = 1";
4166 $sql .=
" AND p.fk_product_type = 0";
4169 if ((
int) $warehouseId > 0) {
4170 $sql .=
" AND EXISTS (SELECT psw.fk_product FROM " . $this->db->prefix() .
"product_stock as psw WHERE psw.reel > 0 AND psw.fk_entrepot = ".(int) $warehouseId.
" AND psw.fk_product = p.rowid)";
4174 $parameters = array(
4175 'filterkey' => &$filterkey,
4178 $reshook = $hookmanager->executeHooks(
'selectProductsListWhere', $parameters);
4179 $sql .= $hookmanager->resPrint;
4181 if ($filterkey !=
'') {
4182 $sqlSupplierSearch =
'';
4187 $search_crit = explode(
' ', $filterkey);
4189 if (count($search_crit) > 1) {
4192 foreach ($search_crit as $crit) {
4196 $sql .=
"(p.ref LIKE '" . $this->db->escape($prefix . $crit) .
"%' OR p.label LIKE '" . $this->db->escape($prefix . $crit) .
"%'";
4198 $sql .=
" OR pl.label LIKE '" . $this->db->escape($prefix . $crit) .
"%'";
4201 $sql .=
" OR pcp.ref_customer LIKE '" . $this->db->escape($prefix . $crit) .
"%'";
4204 $sql .=
" OR p.description LIKE '" . $this->db->escape($prefix . $crit) .
"%'";
4206 $sql .=
" OR pl.description LIKE '" . $this->db->escape($prefix . $crit) .
"%'";
4212 $sqlSupplierSearch .= !empty($sqlSupplierSearch) ?
' AND ' :
'';
4213 $sqlSupplierSearch .=
" pfp.ref_fourn LIKE '" . $this->db->escape($prefix . $crit) .
"%'";
4218 if (count($search_crit) > 1) {
4222 $sql .=
" OR p.barcode LIKE '" . $this->db->escape($prefix . $filterkey) .
"%'";
4227 $sql .=
" OR EXISTS (SELECT pfp.fk_product FROM " . $this->db->prefix() .
"product_fournisseur_price as pfp WHERE p.rowid = pfp.fk_product";
4229 $sql .= $sqlSupplierSearch;
4232 $sql .=
" OR pfp.barcode LIKE '" . $this->db->escape($prefix . $filterkey) .
"%'";
4239 if (count($warehouseStatusArray)) {
4240 $sql .=
" GROUP BY " . $this->db->sanitize($selectFields, 0, 0, 1);
4245 $sql .=
" ORDER BY categorie_product_id ".(getDolGlobalInt(
'PRODUCT_SORT_BY_CATEGORY') == 1 ?
"ASC" :
"DESC");
4247 $sql .= $this->db->order(
"p.ref");
4251 $sql .= $this->db->plimit($limit, 0);
4269 dol_syslog(get_class($this) .
"::select_produits_list search products", LOG_DEBUG);
4273 $result = $this->db->query($sql);
4276 require_once DOL_DOCUMENT_ROOT .
'/product/class/product.class.php';
4277 require_once DOL_DOCUMENT_ROOT .
'/product/dynamic_price/class/price_parser.class.php';
4278 require_once DOL_DOCUMENT_ROOT .
'/core/lib/product.lib.php';
4280 $num = $this->db->num_rows($result);
4285 include_once DOL_DOCUMENT_ROOT .
'/core/lib/ajax.lib.php';
4289 $out .=
'<select class="flat' . ($morecss ?
' ' . $morecss :
'') .
'" name="' . $htmlname .
'" id="' . $htmlname .
'">';
4295 if ($showempty && !is_numeric($showempty)) {
4296 $textifempty = $langs->trans($showempty);
4298 $textifempty .= $langs->trans(
"All");
4301 if ($showempty && !is_numeric($showempty)) {
4302 $textifempty = $langs->trans($showempty);
4306 $out .=
'<option value="-1" selected>' . ($textifempty ? $textifempty :
' ') .
'</option>';
4310 while ($num && $i < $num) {
4313 $objp = $this->db->fetch_object($result);
4315 if ((
getDolGlobalString(
'PRODUIT_CUSTOMER_PRICES_BY_QTY') ||
getDolGlobalString(
'PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES')) && !empty($objp->price_by_qty) && $objp->price_by_qty == 1) {
4316 $sql =
"SELECT rowid, quantity, price, unitprice, remise_percent, remise, price_base_type";
4317 $sql .=
" FROM " . $this->db->prefix() .
"product_price_by_qty";
4318 $sql .=
" WHERE fk_product_price = " . ((int) $objp->price_rowid);
4319 $sql .=
" ORDER BY quantity ASC";
4321 dol_syslog(get_class($this) .
"::select_produits_list search prices by qty", LOG_DEBUG);
4322 $result2 = $this->db->query($sql);
4324 $nb_prices = $this->db->num_rows($result2);
4326 while ($nb_prices && $j < $nb_prices) {
4327 $objp2 = $this->db->fetch_object($result2);
4329 $objp->price_by_qty_rowid = $objp2->rowid;
4330 $objp->price_by_qty_price_base_type = $objp2->price_base_type;
4331 $objp->price_by_qty_quantity = $objp2->quantity;
4332 $objp->price_by_qty_unitprice = $objp2->unitprice;
4333 $objp->price_by_qty_remise_percent = $objp2->remise_percent;
4335 $objp->quantity = $objp2->quantity;
4336 $objp->price = $objp2->price;
4337 $objp->unitprice = $objp2->unitprice;
4338 $objp->remise_percent = $objp2->remise_percent;
4343 $this->constructProductListOption($objp, $opt, $optJson, 0, $selected, $hidepriceinlabel, $filterkey);
4344 '@phan-var-force array{key:string,value:string,label:string,label2:string,desc:string,type:string,price_ht:string,price_ttc:string,price_ht_locale:string,price_ttc_locale:string,pricebasetype:string,tva_tx:string,default_vat_code:string,qty:string,discount:string,duration_value:string,duration_unit:string,pbq:string,labeltrans:string,desctrans:string,ref_customer:string} $optJson';
4351 array_push($outarray, $optJson);
4355 if (
isModEnabled(
'dynamicprices') && !empty($objp->fk_price_expression)) {
4356 $price_product =
new Product($this->db);
4357 $price_product->fetch($objp->rowid,
'',
'',
'1');
4359 require_once DOL_DOCUMENT_ROOT .
'/product/dynamic_price/class/price_parser.class.php';
4361 $price_result = $priceparser->parseProduct($price_product);
4362 if ($price_result >= 0) {
4363 $objp->price = $price_result;
4364 $objp->unitprice = $price_result;
4366 $objp->price_ttc = (float)
price2num($objp->price) * (1 + ($objp->tva_tx / 100));
4367 $objp->price_ttc =
price2num($objp->price_ttc,
'MU');
4370 if (
getDolGlobalInt(
'PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES') && !empty($objp->custprice)) {
4373 $this->constructProductListOption($objp, $opt, $optJson, $price_level, $selected, $hidepriceinlabel, $filterkey);
4378 array_push($outarray, $optJson);
4384 $out .=
'</select>';
4386 $this->db->free($result);
4388 if (empty($outputmode)) {
4394 dol_print_error($this->db);
4415 protected function constructProductListOption(&$objp, &$opt, &$optJson, $price_level, $selected, $hidepriceinlabel = 0, $filterkey =
'', $novirtualstock = 0)
4417 global $langs,
$conf, $user;
4418 global $hookmanager;
4424 $outlabel_translated =
'';
4426 $outdesc_translated =
'';
4432 $outpricebasetype =
'';
4434 $outdefault_vat_code =
'';
4440 $productlabel = $objp->label;
4441 if (!empty($objp->label_translated)) {
4442 $productlabel = $objp->label_translated;
4444 $label = $productlabel;
4445 if (!empty($filterkey) && $filterkey !=
'') {
4446 $label = preg_replace(
'/(' . preg_quote($filterkey,
'/') .
')/i',
'<strong>$1</strong>', $label, 1);
4449 $outkey = $objp->rowid;
4450 $outref = $objp->ref;
4451 $outrefcust = empty($objp->custref) ?
'' : $objp->custref;
4452 $outlabel = $objp->label;
4453 $outdesc = $objp->description;
4455 $outlabel_translated = $objp->label_translated;
4456 $outdesc_translated = $objp->description_translated;
4458 $outbarcode = $objp->barcode;
4459 $outorigin = $objp->fk_country;
4460 $outpbq = empty($objp->price_by_qty_rowid) ?
'' : $objp->price_by_qty_rowid;
4462 $outtype = $objp->fk_product_type;
4467 require_once DOL_DOCUMENT_ROOT .
'/core/lib/company.lib.php';
4473 if (!empty($objp->unit_short)) {
4474 $outvalUnits .=
' - ' . $objp->unit_short;
4478 if (!empty($objp->weight) && $objp->weight_units !==
null) {
4480 $outvalUnits .=
' - ' . $unitToShow;
4482 if ((!empty($objp->length) || !empty($objp->width) || !empty($objp->height)) && $objp->length_units !==
null) {
4483 $unitToShow = $objp->length .
' x ' . $objp->width .
' x ' . $objp->height .
' ' .
measuringUnitString(0,
'size', $objp->length_units);
4484 $outvalUnits .=
' - ' . $unitToShow;
4486 if (!empty($objp->surface) && $objp->surface_units !==
null) {
4488 $outvalUnits .=
' - ' . $unitToShow;
4490 if (!empty($objp->volume) && $objp->volume_units !==
null) {
4492 $outvalUnits .=
' - ' . $unitToShow;
4495 if ($outdurationvalue && $outdurationunit) {
4497 'h' => $langs->trans(
'Hour'),
4498 'd' => $langs->trans(
'Day'),
4499 'w' => $langs->trans(
'Week'),
4500 'm' => $langs->trans(
'Month'),
4501 'y' => $langs->trans(
'Year')
4503 if (isset($da[$outdurationunit])) {
4504 $outvalUnits .=
' - ' . $outdurationvalue .
' ' . $langs->transnoentities($da[$outdurationunit] . ($outdurationvalue > 1 ?
's' :
''));
4511 if ($user->hasRight(
'stock',
'lire')) {
4512 if ($objp->stock > 0) {
4514 } elseif ($objp->stock <= 0) {
4522 $labeltosearch =
'';
4523 $labeltosearch .= $objp->ref;
4524 if (!empty($objp->custref)) {
4525 $labeltosearch .=
' (' . $objp->custref .
')';
4528 $labeltosearch .=
' (' . $outbarcode .
')';
4530 $labeltosearch .=
' - ' . $productlabel;
4532 $labeltosearch .=
' (' .
getCountry($outorigin,
'1') .
')';
4536 $labeltoshowhtml =
'';
4537 $labeltoshowhtml .= $objp->ref;
4538 if (!empty($objp->custref)) {
4539 $labeltoshowhtml .=
' (' . $objp->custref .
')';
4541 if (!empty($filterkey) && $filterkey !=
'') {
4542 $labeltoshowhtml = preg_replace(
'/(' . preg_quote($filterkey,
'/') .
')/i',
'<strong>$1</strong>', $labeltoshowhtml, 1);
4545 $labeltoshowhtml .=
' (' . $outbarcode .
')';
4547 $labeltoshowhtml .=
' - ' .
dol_trunc($label, $maxlengtharticle);
4549 $labeltoshowhtml .=
' (' .
getCountry($outorigin,
'1') .
')';
4553 $labeltoshowstock =
'';
4554 $labeltoshowhtmlstock =
'';
4556 if ($user->hasRight(
'stock',
'lire')) {
4557 $labeltoshowstock .=
' - ' . $langs->trans(
"Stock") .
': ' .
price(
price2num($objp->stock,
'MS'), 0, $langs, 0, 0);
4559 if ($objp->stock > 0) {
4560 $labeltoshowhtmlstock .=
' - <span class="product_line_stock_ok">';
4561 } elseif ($objp->stock <= 0) {
4562 $labeltoshowhtmlstock .=
' - <span class="product_line_stock_too_low">';
4564 $labeltoshowhtmlstock .= $langs->transnoentities(
"Stock") .
': ' .
price(
price2num($objp->stock,
'MS'), 0, $langs, 0, 0);
4565 $labeltoshowhtmlstock .=
'</span>';
4567 if (empty($novirtualstock) &&
getDolGlobalString(
'STOCK_SHOW_VIRTUAL_STOCK_IN_PRODUCTS_COMBO')) {
4568 $langs->load(
"stocks");
4570 $tmpproduct =
new Product($this->db);
4571 $tmpproduct->fetch($objp->rowid,
'',
'',
'', 1, 1, 1);
4572 $tmpproduct->load_virtual_stock();
4573 $virtualstock = $tmpproduct->stock_theorique;
4575 $labeltoshowstock .=
' - ' . $langs->trans(
"VirtualStock") .
':' . $virtualstock;
4577 $labeltoshowhtmlstock .=
' - ' . $langs->transnoentities(
"VirtualStock") .
':';
4578 if ($virtualstock > 0) {
4579 $labeltoshowhtmlstock .=
'<span class="product_line_stock_ok">';
4580 } elseif ($virtualstock <= 0) {
4581 $labeltoshowhtmlstock .=
'<span class="product_line_stock_too_low">';
4583 $labeltoshowhtmlstock .= $virtualstock;
4584 $labeltoshowhtmlstock .=
'</span>';
4593 $labeltoshowprice =
'';
4594 $labeltoshowhtmlprice =
'';
4597 $sql =
"SELECT price, price_ttc, price_base_type, tva_tx, default_vat_code";
4598 $sql .=
" FROM " . $this->db->prefix() .
"product_price";
4599 $sql .=
" WHERE fk_product = " . ((int) $objp->rowid);
4600 $sql .=
" AND entity IN (" .
getEntity(
'productprice') .
")";
4601 $sql .=
" AND price_level = " . ((int) $price_level);
4602 $sql .=
" ORDER BY date_price DESC, rowid DESC";
4605 dol_syslog(get_class($this) .
'::constructProductListOption search price for product ' . $objp->rowid .
' AND level ' . $price_level, LOG_DEBUG);
4606 $result2 = $this->db->query($sql);
4608 $objp2 = $this->db->fetch_object($result2);
4611 if ($objp2->price_base_type ==
'HT') {
4612 $labeltoshowprice .=
' - ' .
price($objp2->price, 1, $langs, 0, 0, -1,
$conf->currency) .
' ' . $langs->trans(
"HT");
4613 $labeltoshowhtmlprice .=
' - ' .
price($objp2->price, 0, $langs, 0, 0, -1,
$conf->currency) .
' ' . $langs->transnoentities(
"HT");
4615 $labeltoshowprice .=
' - ' .
price($objp2->price_ttc, 1, $langs, 0, 0, -1,
$conf->currency) .
' ' . $langs->trans(
"TTC");
4616 $labeltoshowhtmlprice .=
' - ' .
price($objp2->price_ttc, 0, $langs, 0, 0, -1,
$conf->currency) .
' ' . $langs->transnoentities(
"TTC");
4618 $outprice_ht =
price($objp2->price);
4619 $outprice_ttc =
price($objp2->price_ttc);
4620 $outpricebasetype = $objp2->price_base_type;
4622 $outtva_tx = $objp2->tva_tx;
4623 $outdefault_vat_code = $objp2->default_vat_code;
4625 $outtva_tx = $objp->tva_tx;
4626 $outdefault_vat_code = $objp->default_vat_code;
4630 dol_print_error($this->db);
4635 if (empty($hidepriceinlabel) && !empty($objp->quantity) && $objp->quantity >= 1 && (
getDolGlobalString(
'PRODUIT_CUSTOMER_PRICES_BY_QTY') ||
getDolGlobalString(
'PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES'))) {
4637 $outqty = $objp->quantity;
4638 $outdiscount = $objp->remise_percent;
4639 if ($objp->quantity == 1) {
4640 $labeltoshowprice .=
' - ' .
price($objp->unitprice, 1, $langs, 0, 0, -1,
$conf->currency) .
"/";
4641 $labeltoshowhtmlprice .=
' - ' .
price($objp->unitprice, 0, $langs, 0, 0, -1,
$conf->currency) .
"/";
4642 $labeltoshowprice .= $langs->trans(
"Unit");
4643 $labeltoshowhtmlprice .= $langs->transnoentities(
"Unit");
4645 $labeltoshowprice .=
' - ' .
price($objp->price, 1, $langs, 0, 0, -1,
$conf->currency) .
"/" . $objp->quantity;
4646 $labeltoshowhtmlprice .=
' - ' .
price($objp->price, 0, $langs, 0, 0, -1,
$conf->currency) .
"/" . $objp->quantity;
4647 $labeltoshowprice .= $langs->trans(
"Units");
4648 $labeltoshowhtmlprice .= $langs->transnoentities(
"Units");
4651 $outprice_ht =
price($objp->unitprice);
4652 $outprice_ttc =
price($objp->unitprice * (1 + ($objp->tva_tx / 100)));
4653 $outpricebasetype = $objp->price_base_type;
4654 $outtva_tx = $objp->tva_tx;
4655 $outdefault_vat_code = $objp->default_vat_code;
4657 if (empty($hidepriceinlabel) && !empty($objp->quantity) && $objp->quantity >= 1) {
4658 $labeltoshowprice .=
" (" .
price($objp->unitprice, 1, $langs, 0, 0, -1,
$conf->currency) .
"/" . $langs->trans(
"Unit") .
")";
4659 $labeltoshowhtmlprice .=
" (" .
price($objp->unitprice, 0, $langs, 0, 0, -1,
$conf->currency) .
"/" . $langs->transnoentities(
"Unit") .
")";
4661 if (empty($hidepriceinlabel) && !empty($objp->remise_percent) && $objp->remise_percent >= 1) {
4662 $labeltoshowprice .=
" - " . $langs->trans(
"Discount") .
" : " .
vatrate($objp->remise_percent) .
' %';
4663 $labeltoshowhtmlprice .=
" - " . $langs->transnoentities(
"Discount") .
" : " .
vatrate($objp->remise_percent) .
' %';
4668 if (!empty($objp->idprodcustprice)) {
4671 if ($objp->custprice_base_type ==
'HT') {
4672 $labeltoshowprice .=
' - ' .
price($objp->custprice, 1, $langs, 0, 0, -1,
$conf->currency) .
' ' . $langs->trans(
"HT");
4673 $labeltoshowhtmlprice .=
' - ' .
price($objp->custprice, 0, $langs, 0, 0, -1,
$conf->currency) .
' ' . $langs->transnoentities(
"HT");
4675 $labeltoshowprice .=
' - ' .
price($objp->custprice_ttc, 1, $langs, 0, 0, -1,
$conf->currency) .
' ' . $langs->trans(
"TTC");
4676 $labeltoshowhtmlprice .=
' - ' .
price($objp->custprice_ttc, 0, $langs, 0, 0, -1,
$conf->currency) .
' ' . $langs->transnoentities(
"TTC");
4679 $outprice_ht =
price($objp->custprice);
4680 $outprice_ttc =
price($objp->custprice_ttc);
4681 $outpricebasetype = $objp->custprice_base_type;
4682 $outtva_tx = $objp->custtva_tx;
4683 $outdefault_vat_code = $objp->custdefault_vat_code;
4684 $outdiscount = $objp->custdiscount_percent;
4689 if (empty($hidepriceinlabel) && !$found) {
4690 if ($objp->price_base_type ==
'HT') {
4691 $labeltoshowprice .=
' - ' .
price($objp->price, 1, $langs, 0, 0, -1,
$conf->currency) .
' ' . $langs->trans(
"HT");
4692 $labeltoshowhtmlprice .=
' - ' .
price($objp->price, 0, $langs, 0, 0, -1,
$conf->currency) .
' ' . $langs->transnoentities(
"HT");
4694 $labeltoshowprice .=
' - ' .
price($objp->price_ttc, 1, $langs, 0, 0, -1,
$conf->currency) .
' ' . $langs->trans(
"TTC");
4695 $labeltoshowhtmlprice .=
' - ' .
price($objp->price_ttc, 0, $langs, 0, 0, -1,
$conf->currency) .
' ' . $langs->transnoentities(
"TTC");
4697 $outprice_ht =
price($objp->price);
4698 $outprice_ttc =
price($objp->price_ttc);
4699 $outpricebasetype = $objp->price_base_type;
4700 $outtva_tx = $objp->tva_tx;
4701 $outdefault_vat_code = $objp->default_vat_code;
4704 $optiontext = $labeltosearch.$outvalUnits.$labeltoshowprice.$labeltoshowstock;
4705 $optionhtml = $labeltoshowhtml.$outvalUnits.$labeltoshowhtmlprice.$labeltoshowhtmlstock;
4709 $opt =
'<option value="' . $objp->rowid .
'"';
4710 $opt .= ($objp->rowid == $selected) ?
' selected' :
'';
4711 if (!empty($objp->price_by_qty_rowid) && $objp->price_by_qty_rowid > 0) {
4712 $opt .=
' pbq="' . $objp->price_by_qty_rowid .
'" data-pbq="' . $objp->price_by_qty_rowid .
'" data-pbqup="' . $objp->price_by_qty_unitprice .
'" data-pbqbase="' . $objp->price_by_qty_price_base_type .
'" data-pbqqty="' . $objp->price_by_qty_quantity .
'" data-pbqpercent="' . $objp->price_by_qty_remise_percent .
'"';
4715 $opt .=
' data-labeltrans="' .
dol_escape_htmltag($outlabel_translated, 0, 0,
'', 0, 1) .
'"';
4719 if ($stocktag == 1) {
4720 $opt .=
' class="product_line_stock_ok" data-html="'.dolPrintHTMLForAttribute($labeltoshowhtml, 0, array(
'strong')).dolPrintHTMLForAttribute($outvalUnits).$labeltoshowhtmlprice.dolPrintHTMLForAttribute($labeltoshowhtmlstock).
'"';
4723 if ($stocktag == -1) {
4724 $opt .=
' class="product_line_stock_too_low" data-html="'.dolPrintHTMLForAttribute($labeltoshowhtml, 0, array(
'strong')).dolPrintHTMLForAttribute($outvalUnits).$labeltoshowhtmlprice.dolPrintHTMLForAttribute($labeltoshowhtmlstock).
'"';
4727 $opt .=
' data-html="'.$optionhtmlforattribute.
'" data-select-html="'.$optionhtmlforattribute.
'"';
4733 $outval .= $labeltoshowhtml;
4736 $outval .= $outvalUnits;
4739 $outval .= $labeltoshowhtmlprice;
4742 $outval .= $labeltoshowhtmlstock;
4745 $parameters = array(
'objp' => $objp);
4746 $reshook = $hookmanager->executeHooks(
'constructProductListOption', $parameters);
4747 if (empty($reshook)) {
4748 $opt .= $hookmanager->resPrint;
4750 $opt = $hookmanager->resPrint;
4753 $opt .=
"</option>\n";
4758 'label2' => $outlabel,
4762 'price_ttc' =>
price2num($outprice_ttc),
4765 'pricebasetype' => $outpricebasetype,
4766 'tva_tx' => $outtva_tx,
4767 'default_vat_code' => $outdefault_vat_code,
4769 'discount' => $outdiscount,
4770 'duration_value' => $outdurationvalue,
4771 'duration_unit' => $outdurationunit,
4773 'labeltrans' => $outlabel_translated,
4774 'desctrans' => $outdesc_translated,
4775 'ref_customer' => $outrefcust
4797 public function select_produits_fournisseurs($socid, $selected =
'', $htmlname =
'productid', $filtertype =
'', $notused =
'', $ajaxoptions = array(), $hidelabel = 0, $alsoproductwithnosupplierprice = 0, $morecss =
'', $placeholder =
'', $nooutput = 0)
4800 global $langs,
$conf;
4801 global $price_level, $status, $finished;
4803 if (!isset($status)) {
4807 $selected_input_value =
'';
4809 $regtmpsel = array();
4810 if ((
int) $selected > 0) {
4811 require_once DOL_DOCUMENT_ROOT .
'/product/class/product.class.php';
4812 $producttmpselect =
new Product($this->db);
4813 $producttmpselect->fetch((
int) $selected);
4814 $selected_input_value = $producttmpselect->ref;
4815 unset($producttmpselect);
4816 } elseif (preg_match(
'/^idprod_([0-9]+)$/', (
string) $selected, $regtmpsel)) {
4818 require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
4819 $producttmpselect =
new Product($this->db);
4820 $producttmpselect->fetch((
int) $regtmpsel[1]);
4821 $selected_input_value = $producttmpselect->ref;
4822 unset($producttmpselect);
4826 $urloption = ($socid > 0 ?
'socid=' . $socid .
'&' :
'') .
'htmlname=' . $htmlname .
'&outjson=1&price_level=' . $price_level .
'&type=' . $filtertype .
'&mode=2&status=' . $status .
'&finished=' . $finished .
'&alsoproductwithnosupplierprice=' . $alsoproductwithnosupplierprice;
4828 $s = ($hidelabel ?
'' : $langs->trans(
"RefOrLabel") .
' : ') .
'<input type="text" class="'.$morecss.
'" name="search_' . $htmlname .
'" id="search_' . $htmlname .
'" value="' . $selected_input_value .
'"' . ($placeholder ?
' placeholder="' . $placeholder .
'"' :
'') .
' spellcheck="false">';
4830 $s .=
ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT .
'/product/ajax/products.php', $urloption,
getDolGlobalInt(
'PRODUIT_USE_SEARCH_TO_SELECT'), 0, $ajaxoptions);
4832 $s = $this->select_produits_fournisseurs_list($socid, $selected, $htmlname, $filtertype, $notused,
'', $status, 0, 0, $alsoproductwithnosupplierprice, $morecss,
getDolGlobalInt(
'SUPPLIER_SHOW_STOCK_IN_PRODUCTS_COMBO'), $placeholder);
4862 public function select_produits_fournisseurs_list($socid, $selected =
'', $htmlname =
'productid', $filtertype =
'', $notused =
'', $filterkey =
'', $statut = -1, $outputmode = 0, $limit = 100, $alsoproductwithnosupplierprice = 0, $morecss =
'', $showstockinlist = 0, $placeholder =
'')
4865 global $langs,
$conf, $user;
4866 global $hookmanager;
4869 $outarray = array();
4873 $langs->load(
'stocks');
4876 $langs->load(
'other');
4879 $sql =
"SELECT p.rowid, p.ref, p.label, p.price, p.duration, p.fk_product_type, p.stock, p.tva_tx as tva_tx_sale, p.default_vat_code as default_vat_code_sale,";
4880 $sql .=
" pfp.ref_fourn, pfp.rowid as idprodfournprice, pfp.price as fprice, pfp.quantity, pfp.remise_percent, pfp.remise, pfp.unitprice, pfp.barcode";
4881 $sql .=
", pfp.multicurrency_code, pfp.multicurrency_unitprice";
4882 $sql .=
", pfp.fk_supplier_price_expression, pfp.fk_product, pfp.tva_tx, pfp.default_vat_code, pfp.fk_soc, s.nom as name";
4883 $sql .=
", pfp.supplier_reputation";
4886 $sql .=
", pfp.desc_fourn as description";
4888 $sql .=
", p.description";
4892 $sql .=
", u.label as unit_long, u.short_label as unit_short, p.weight, p.weight_units, p.length, p.length_units, p.width, p.width_units, p.height, p.height_units, p.surface, p.surface_units, p.volume, p.volume_units";
4897 $reshook = $hookmanager->executeHooks(
'selectSuppliersProductsListSelect', $parameters);
4898 $sql .= $hookmanager->resPrint;
4900 $sql .=
" FROM " . $this->db->prefix() .
"product as p";
4904 $reshook = $hookmanager->executeHooks(
'selectSuppliersProductsListFrom', $parameters);
4905 $sql .= $hookmanager->resPrint;
4907 $sql .=
" LEFT JOIN " . $this->db->prefix() .
"product_fournisseur_price as pfp ON ( p.rowid = pfp.fk_product AND pfp.entity IN (" .
getEntity(
'product') .
") )";
4909 $sql .=
" AND pfp.fk_soc = " . ((int) $socid);
4911 $sql .=
" LEFT JOIN " . $this->db->prefix() .
"societe as s ON pfp.fk_soc = s.rowid";
4914 $sql .=
" LEFT JOIN " . $this->db->prefix() .
"c_units u ON u.rowid = p.fk_unit";
4916 $sql .=
" WHERE p.entity IN (" .
getEntity(
'product') .
")";
4917 if ($statut != -1) {
4918 $sql .=
" AND p.tobuy = " . ((int) $statut);
4920 if (strval($filtertype) !=
'') {
4921 $sql .=
" AND p.fk_product_type = " . ((int) $filtertype);
4925 $parameters = array();
4926 $reshook = $hookmanager->executeHooks(
'selectSuppliersProductsListWhere', $parameters);
4927 $sql .= $hookmanager->resPrint;
4929 if ($filterkey !=
'') {
4933 $search_crit = explode(
' ', $filterkey);
4935 if (count($search_crit) > 1) {
4938 foreach ($search_crit as $crit) {
4942 $sql .=
"(pfp.ref_fourn LIKE '" . $this->db->escape($prefix . $crit) .
"%' OR p.ref LIKE '" . $this->db->escape($prefix . $crit) .
"%' OR p.label LIKE '" . $this->db->escape($prefix . $crit) .
"%'";
4944 $sql .=
" OR pfp.desc_fourn LIKE '" . $this->db->escape($prefix . $crit) .
"%'";
4949 if (count($search_crit) > 1) {
4953 $sql .=
" OR p.barcode LIKE '" . $this->db->escape($prefix . $filterkey) .
"%'";
4954 $sql .=
" OR pfp.barcode LIKE '" . $this->db->escape($prefix . $filterkey) .
"%'";
4958 $sql .=
" ORDER BY pfp.ref_fourn DESC, pfp.quantity ASC";
4959 $sql .= $this->db->plimit($limit, 0);
4963 dol_syslog(get_class($this) .
"::select_produits_fournisseurs_list", LOG_DEBUG);
4964 $result = $this->db->query($sql);
4966 require_once DOL_DOCUMENT_ROOT .
'/product/dynamic_price/class/price_parser.class.php';
4967 require_once DOL_DOCUMENT_ROOT .
'/core/lib/product.lib.php';
4969 $num = $this->db->num_rows($result);
4972 $out .=
'<select class="flat ' . ($morecss ?
' ' . $morecss :
'') .
'" id="' . $htmlname .
'" name="' . $htmlname .
'">';
4974 $out .=
'<option value="-1" selected>' . ($placeholder ? $placeholder :
' ') .
'</option>';
4976 $out .=
'<option value="-1">' . ($placeholder ? $placeholder :
' ') .
'</option>';
4981 $objp = $this->db->fetch_object($result);
4983 if (is_null($objp->idprodfournprice)) {
4985 $objp->tva_tx = $objp->tva_tx_sale;
4986 $objp->default_vat_code = $objp->default_vat_code_sale;
4989 $outkey = $objp->idprodfournprice;
4990 if (!$outkey && $alsoproductwithnosupplierprice) {
4991 $outkey =
'idprod_' . $objp->rowid;
4994 $outref = $objp->ref;
4995 $outbarcode = $objp->barcode;
4998 $outtype = $objp->fk_product_type;
5005 if (!empty($objp->unit_short)) {
5006 $outvalUnits .=
' - ' . $objp->unit_short;
5008 if (!empty($objp->weight) && $objp->weight_units !==
null) {
5010 $outvalUnits .=
' - ' . $unitToShow;
5012 if ((!empty($objp->length) || !empty($objp->width) || !empty($objp->height)) && $objp->length_units !==
null) {
5013 $unitToShow = $objp->length .
' x ' . $objp->width .
' x ' . $objp->height .
' ' .
measuringUnitString(0,
'size', $objp->length_units);
5014 $outvalUnits .=
' - ' . $unitToShow;
5016 if (!empty($objp->surface) && $objp->surface_units !==
null) {
5018 $outvalUnits .=
' - ' . $unitToShow;
5020 if (!empty($objp->volume) && $objp->volume_units !==
null) {
5022 $outvalUnits .=
' - ' . $unitToShow;
5024 if ($outdurationvalue && $outdurationunit) {
5026 'h' => $langs->trans(
'Hour'),
5027 'd' => $langs->trans(
'Day'),
5028 'w' => $langs->trans(
'Week'),
5029 'm' => $langs->trans(
'Month'),
5030 'y' => $langs->trans(
'Year')
5032 if (isset($da[$outdurationunit])) {
5033 $outvalUnits .=
' - ' . $outdurationvalue .
' ' . $langs->transnoentities($da[$outdurationunit] . ($outdurationvalue > 1 ?
's' :
''));
5038 $objRef = $objp->ref;
5039 if ($filterkey && $filterkey !=
'') {
5040 $objRef = preg_replace(
'/(' . preg_quote($filterkey,
'/') .
')/i',
'<strong>$1</strong>', $objRef, 1);
5042 $objRefFourn = $objp->ref_fourn;
5043 if ($filterkey && $filterkey !=
'') {
5044 $objRefFourn = preg_replace(
'/(' . preg_quote($filterkey,
'/') .
')/i',
'<strong>$1</strong>', $objRefFourn, 1);
5046 $label = $objp->label;
5047 if ($filterkey && $filterkey !=
'') {
5048 $label = preg_replace(
'/(' . preg_quote($filterkey,
'/') .
')/i',
'<strong>$1</strong>', $label, 1);
5051 switch ($objp->fk_product_type) {
5063 if (empty($picto)) {
5066 $optlabel = img_object(
'', $picto,
'class="paddingright classfortooltip"', 0, 0, 1);
5069 $optlabel .= $objp->ref;
5070 if (!empty($objp->idprodfournprice) && ($objp->ref != $objp->ref_fourn)) {
5071 $optlabel .=
' <span class="opacitymedium">(' . $objp->ref_fourn .
')</span>';
5073 if (
isModEnabled(
'barcode') && !empty($objp->barcode)) {
5074 $optlabel .=
' (' . $outbarcode .
')';
5076 $optlabel .=
' - ' .
dol_trunc($label, $maxlengtharticle);
5078 $outvallabel = $objRef;
5079 if (!empty($objp->idprodfournprice) && ($objp->ref != $objp->ref_fourn)) {
5080 $outvallabel .=
' (' . $objRefFourn .
')';
5082 if (
isModEnabled(
'barcode') && !empty($objp->barcode)) {
5083 $outvallabel .=
' (' . $outbarcode .
')';
5085 $outvallabel .=
' - ' .
dol_trunc($label, $maxlengtharticle);
5087 $outsearchlabel = implode(
' ', array_filter(array(
5088 (
string) $objp->ref,
5089 (
string) $objp->ref_fourn,
5090 (
string) $objp->barcode,
5091 (
string) $objp->label,
5093 ), function (
string $value):
bool {
5094 return $value !==
'';
5098 $optlabel .= $outvalUnits;
5099 $outvallabel .= $outvalUnits;
5101 if (!empty($objp->idprodfournprice)) {
5102 $outqty = $objp->quantity;
5103 $outdiscount = $objp->remise_percent;
5104 if (
isModEnabled(
'dynamicprices') && !empty($objp->fk_supplier_price_expression)) {
5106 $prod_supplier->product_fourn_price_id = $objp->idprodfournprice;
5107 $prod_supplier->id = $objp->fk_product;
5108 $prod_supplier->fourn_qty = $objp->quantity;
5109 $prod_supplier->fourn_tva_tx = $objp->tva_tx;
5110 $prod_supplier->fk_supplier_price_expression = $objp->fk_supplier_price_expression;
5112 require_once DOL_DOCUMENT_ROOT .
'/product/dynamic_price/class/price_parser.class.php';
5114 $price_result = $priceparser->parseProductSupplier($prod_supplier);
5115 if ($price_result >= 0) {
5116 $objp->fprice = $price_result;
5117 if ($objp->quantity >= 1) {
5118 $objp->unitprice = $objp->fprice / $objp->quantity;
5122 if ($objp->quantity == 1) {
5123 $optlabel .=
' - ' .
price($objp->fprice * (
getDolGlobalString(
'DISPLAY_DISCOUNTED_SUPPLIER_PRICE') ? (1 - $objp->remise_percent / 100) : 1), 1, $langs, 0, 0, -1,
$conf->currency) .
"/";
5124 $outvallabel .=
' - ' .
price($objp->fprice * (
getDolGlobalString(
'DISPLAY_DISCOUNTED_SUPPLIER_PRICE') ? (1 - $objp->remise_percent / 100) : 1), 0, $langs, 0, 0, -1,
$conf->currency) .
"/";
5125 $optlabel .= $langs->trans(
"Unit");
5126 $outvallabel .= $langs->transnoentities(
"Unit");
5128 $optlabel .=
' - ' .
price($objp->fprice * (
getDolGlobalString(
'DISPLAY_DISCOUNTED_SUPPLIER_PRICE') ? (1 - $objp->remise_percent / 100) : 1), 1, $langs, 0, 0, -1,
$conf->currency) .
"/" . $objp->quantity;
5129 $outvallabel .=
' - ' .
price($objp->fprice * (
getDolGlobalString(
'DISPLAY_DISCOUNTED_SUPPLIER_PRICE') ? (1 - $objp->remise_percent / 100) : 1), 0, $langs, 0, 0, -1,
$conf->currency) .
"/" . $objp->quantity;
5130 $optlabel .=
' ' . $langs->trans(
"Units");
5131 $outvallabel .=
' ' . $langs->transnoentities(
"Units");
5134 if ($objp->quantity != 1) {
5135 $optlabel .=
" (" .
price($objp->unitprice * (
getDolGlobalString(
'DISPLAY_DISCOUNTED_SUPPLIER_PRICE') ? (1 - $objp->remise_percent / 100) : 1), 1, $langs, 0, 0, -1,
$conf->currency) .
"/" . $langs->trans(
"Unit") .
")";
5136 $outvallabel .=
" (" .
price($objp->unitprice * (
getDolGlobalString(
'DISPLAY_DISCOUNTED_SUPPLIER_PRICE') ? (1 - $objp->remise_percent / 100) : 1), 0, $langs, 0, 0, -1,
$conf->currency) .
"/" . $langs->transnoentities(
"Unit") .
")";
5138 if ($objp->remise_percent >= 1) {
5139 $optlabel .=
" - " . $langs->trans(
"Discount") .
" : " .
vatrate($objp->remise_percent) .
' %';
5140 $outvallabel .=
" - " . $langs->transnoentities(
"Discount") .
" : " .
vatrate($objp->remise_percent) .
' %';
5142 if ($objp->duration) {
5143 $optlabel .=
" - " . $objp->duration;
5144 $outvallabel .=
" - " . $objp->duration;
5147 $optlabel .=
" - " .
dol_trunc($objp->name, 8);
5148 $outvallabel .=
" - " .
dol_trunc($objp->name, 8);
5150 if ($objp->supplier_reputation) {
5152 $reputations = array(
'' => $langs->trans(
'Standard'),
'FAVORITE' => $langs->trans(
'Favorite'),
'NOTTHGOOD' => $langs->trans(
'NotTheGoodQualitySupplier'),
'DONOTORDER' => $langs->trans(
'DoNotOrderThisProductToThisSupplier'));
5154 $optlabel .=
" - " . $reputations[$objp->supplier_reputation];
5155 $outvallabel .=
" - " . $reputations[$objp->supplier_reputation];
5158 $optlabel .=
" - <span class='opacitymedium'>" . $langs->trans(
"NoPriceDefinedForThisSupplier") .
'</span>';
5159 $outvallabel .=
' - ' . $langs->transnoentities(
"NoPriceDefinedForThisSupplier");
5163 $novirtualstock = ($showstockinlist == 2);
5165 if ($user->hasRight(
'stock',
'lire')) {
5166 $outvallabel .=
' - ' . $langs->trans(
"Stock") .
': ' .
price(
price2num($objp->stock,
'MS'), 0, $langs, 0, 0);
5168 if ($objp->stock > 0) {
5169 $optlabel .=
' - <span class="product_line_stock_ok">';
5170 } elseif ($objp->stock <= 0) {
5171 $optlabel .=
' - <span class="product_line_stock_too_low">';
5173 $optlabel .= $langs->transnoentities(
"Stock") .
':' .
price(
price2num($objp->stock,
'MS'));
5174 $optlabel .=
'</span>';
5175 if (empty($novirtualstock) &&
getDolGlobalString(
'STOCK_SHOW_VIRTUAL_STOCK_IN_PRODUCTS_COMBO')) {
5176 $langs->load(
"stocks");
5178 $tmpproduct =
new Product($this->db);
5179 $tmpproduct->fetch($objp->rowid,
'',
'',
'', 1, 1, 1);
5180 $tmpproduct->load_virtual_stock();
5181 $virtualstock = $tmpproduct->stock_theorique;
5183 $outvallabel .=
' - ' . $langs->trans(
"VirtualStock") .
':' . $virtualstock;
5185 $optlabel .=
' - ' . $langs->transnoentities(
"VirtualStock") .
':';
5186 if ($virtualstock > 0) {
5187 $optlabel .=
'<span class="product_line_stock_ok">';
5188 } elseif ($virtualstock <= 0) {
5189 $optlabel .=
'<span class="product_line_stock_too_low">';
5191 $optlabel .= $virtualstock;
5192 $optlabel .=
'</span>';
5199 $optstart =
'<option value="' . $outkey .
'"';
5200 if ($selected && preg_match(
'/^idprod_/', (
string) $selected) && (
string) $selected ==
'idprod_'.$objp->rowid) {
5201 $optstart .=
' selected';
5202 } elseif ($selected && (
string) $selected == (
string) $objp->idprodfournprice) {
5203 $optstart .=
' selected';
5206 if (empty($objp->idprodfournprice) && empty($alsoproductwithnosupplierprice)) {
5207 $optstart .=
' disabled';
5210 if (!empty($objp->idprodfournprice) && $objp->idprodfournprice > 0) {
5219 $optstart .=
' data-default-vat-code="' .
dol_escape_htmltag($objp->default_vat_code) .
'"';
5222 $optstart .=
' data-multicurrency-code="' .
dol_escape_htmltag($objp->multicurrency_code) .
'"';
5226 $optstart .=
' data-description="' .
dol_escape_htmltag($objp->description, 0, 1) .
'"';
5230 $outarrayentry = array(
5233 'label' => $outvallabel,
5234 'labelhtml' => $optlabel,
5236 'price_qty_ht' =>
price2num($objp->fprice,
'MU'),
5237 'price_unit_ht' =>
price2num($objp->unitprice,
'MU'),
5238 'price_ht' =>
price2num($objp->unitprice,
'MU'),
5239 'tva_tx_formated' =>
price($objp->tva_tx, 0, $langs, 1, -1, 2),
5241 'default_vat_code' => $objp->default_vat_code,
5242 'supplier_ref' => $objp->ref_fourn,
5243 'discount' => $outdiscount,
5245 'duration_value' => $outdurationvalue,
5246 'duration_unit' => $outdurationunit,
5247 'disabled' => empty($objp->idprodfournprice),
5248 'description' => $objp->description
5251 $outarrayentry[
'multicurrency_code'] = $objp->multicurrency_code;
5252 $outarrayentry[
'multicurrency_unitprice'] =
price2num($objp->multicurrency_unitprice,
'MU');
5254 $parameters = array(
5256 'optstart' => &$optstart,
5257 'optlabel' => &$optlabel,
5258 'outvallabel' => &$outvallabel,
5259 'outarrayentry' => &$outarrayentry,
5262 $reshook = $hookmanager->executeHooks(
'selectProduitsFournisseurListOption', $parameters, $this);
5268 $out .= $optstart .
' data-html="' .
dol_escape_htmltag($optlabel) .
'">' . $optlabel .
"</option>\n";
5269 $outarraypush = array(
5272 'label' => $outvallabel,
5273 'labelhtml' => $optlabel,
5275 'price_qty_ht' =>
price2num($objp->fprice,
'MU'),
5276 'price_qty_ht_locale' =>
price($objp->fprice),
5277 'price_unit_ht' =>
price2num($objp->unitprice,
'MU'),
5278 'price_unit_ht_locale' =>
price($objp->unitprice),
5279 'price_ht' =>
price2num($objp->unitprice,
'MU'),
5280 'tva_tx_formated' =>
price($objp->tva_tx),
5282 'default_vat_code' => $objp->default_vat_code,
5283 'supplier_ref' => $objp->ref_fourn,
5284 'discount' => $outdiscount,
5286 'duration_value' => $outdurationvalue,
5287 'duration_unit' => $outdurationunit,
5288 'disabled' => empty($objp->idprodfournprice),
5289 'description' => $objp->description
5292 $outarraypush[
'multicurrency_code'] = $objp->multicurrency_code;
5293 $outarraypush[
'multicurrency_unitprice'] =
price2num($objp->multicurrency_unitprice,
'MU');
5295 array_push($outarray, $outarraypush);
5308 $out .=
'</select>';
5310 $this->db->free($result);
5312 include_once DOL_DOCUMENT_ROOT .
'/core/lib/ajax.lib.php';
5315 dol_print_error($this->db);
5318 if (empty($outputmode)) {
5337 global $langs,
$conf;
5339 $langs->load(
'stocks');
5341 $sql =
"SELECT p.rowid, p.ref, p.label, p.price, p.duration, pfp.fk_soc,";
5342 $sql .=
" pfp.ref_fourn, pfp.rowid as idprodfournprice, pfp.price as fprice, pfp.remise_percent, pfp.quantity, pfp.unitprice,";
5343 $sql .=
" pfp.fk_supplier_price_expression, pfp.fk_product, pfp.tva_tx, s.nom as name";
5344 $sql .=
" FROM " . $this->db->prefix() .
"product as p";
5345 $sql .=
" LEFT JOIN " . $this->db->prefix() .
"product_fournisseur_price as pfp ON p.rowid = pfp.fk_product";
5346 $sql .=
" LEFT JOIN " . $this->db->prefix() .
"societe as s ON pfp.fk_soc = s.rowid";
5347 $sql .=
" WHERE pfp.entity IN (" .
getEntity(
'productsupplierprice') .
")";
5348 $sql .=
" AND p.tobuy = 1";
5349 $sql .=
" AND s.fournisseur = 1";
5350 $sql .=
" AND p.rowid = " . ((int) $productid);
5352 $sql .=
" ORDER BY s.nom, pfp.ref_fourn DESC";
5354 $sql .=
" ORDER BY pfp.unitprice - pfp.unitprice * pfp.remise_percent / 100 ASC";
5357 dol_syslog(get_class($this) .
"::select_product_fourn_price", LOG_DEBUG);
5358 $result = $this->db->query($sql);
5361 $num = $this->db->num_rows($result);
5363 $form =
'<select class="flat" id="select_' . $htmlname .
'" name="' . $htmlname .
'">';
5366 $form .=
'<option value="0">-- ' . $langs->trans(
"NoSupplierPriceDefinedForThisProduct") .
' --</option>';
5368 require_once DOL_DOCUMENT_ROOT .
'/product/dynamic_price/class/price_parser.class.php';
5369 $form .=
'<option value="0"> </option>';
5373 $objp = $this->db->fetch_object($result);
5375 $opt =
'<option value="' . $objp->idprodfournprice .
'"';
5377 if ($num == 1 || ($selected_supplier > 0 && $objp->fk_soc == $selected_supplier) || ($i == 0 &&
getDolGlobalString(
'PRODUCT_BEST_SUPPLIER_PRICE_PRESELECTED'))) {
5378 $opt .=
' selected';
5380 $opt .=
'>' . $objp->name .
' - ' . $objp->ref_fourn .
' - ';
5382 if (
isModEnabled(
'dynamicprices') && !empty($objp->fk_supplier_price_expression)) {
5384 $prod_supplier->product_fourn_price_id = $objp->idprodfournprice;
5385 $prod_supplier->id = $productid;
5386 $prod_supplier->fourn_qty = $objp->quantity;
5387 $prod_supplier->fourn_tva_tx = $objp->tva_tx;
5388 $prod_supplier->fk_supplier_price_expression = $objp->fk_supplier_price_expression;
5390 require_once DOL_DOCUMENT_ROOT .
'/product/dynamic_price/class/price_parser.class.php';
5392 $price_result = $priceparser->parseProductSupplier($prod_supplier);
5393 if ($price_result >= 0) {
5394 $objp->fprice = $price_result;
5395 if ($objp->quantity >= 1) {
5396 $objp->unitprice = $objp->fprice / $objp->quantity;
5400 if ($objp->quantity == 1) {
5401 $opt .=
price($objp->fprice * (
getDolGlobalString(
'DISPLAY_DISCOUNTED_SUPPLIER_PRICE') ? (1 - $objp->remise_percent / 100) : 1), 1, $langs, 0, 0, -1,
$conf->currency) .
"/";
5404 $opt .= $objp->quantity .
' ';
5406 if ($objp->quantity == 1) {
5407 $opt .= $langs->trans(
"Unit");
5409 $opt .= $langs->trans(
"Units");
5411 if ($objp->quantity > 1) {
5413 $opt .=
price($objp->unitprice * (
getDolGlobalString(
'DISPLAY_DISCOUNTED_SUPPLIER_PRICE') ? (1 - $objp->remise_percent / 100) : 1), 1, $langs, 0, 0, -1,
$conf->currency) .
"/" . $langs->trans(
"Unit");
5415 if ($objp->duration) {
5416 $opt .=
" - " . $objp->duration;
5418 $opt .=
"</option>\n";
5425 $form .=
'</select>';
5426 $this->db->free($result);
5429 dol_print_error($this->db);
5444 global $langs, $hookmanager;
5446 $num = count($this->cache_conditions_paiements);
5453 $this->cache_conditions_paiements = array();
5455 $sql =
"SELECT rowid, code, libelle as label, deposit_percent, entity";
5456 $sql .=
" FROM " . $this->db->prefix() .
'c_payment_term';
5457 $sql .=
" WHERE entity IN (" .
getEntity(
'c_payment_term') .
")";
5458 $sql .=
" AND active > 0";
5459 $sql .=
" ORDER BY sortorder";
5461 $resql = $this->db->query($sql);
5463 $num = $this->db->num_rows($resql);
5466 $obj = $this->db->fetch_object($resql);
5469 $label = ($langs->trans(
"PaymentConditionShort" . $obj->code) !=
"PaymentConditionShort" . $obj->code ? $langs->trans(
"PaymentConditionShort" . $obj->code) : ($obj->label !=
'-' ? $obj->label :
''));
5471 $this->cache_conditions_paiements[$obj->rowid][
'code'] = (string) $obj->code;
5472 $this->cache_conditions_paiements[$obj->rowid][
'label'] = (string) $label;
5473 $this->cache_conditions_paiements[$obj->rowid][
'deposit_percent'] = (string) $obj->deposit_percent;
5474 $this->cache_conditions_paiements[$obj->rowid][
'entity'] = (int) $obj->entity;
5479 $parameters = array(
'dictionary' =>
'paymentterm');
5480 $reshook = $hookmanager->executeHooks(
'loadDictionaryCache', $parameters, $this);
5481 if (empty($reshook)) {
5482 if (is_array($hookmanager->resArray) && count($hookmanager->resArray)) {
5483 $this->cache_conditions_paiements = array_merge($this->cache_conditions_paiements, $hookmanager->resArray);
5486 $this->cache_conditions_paiements = $hookmanager->resArray;
5493 dol_print_error($this->db);
5510 $this->cache_rule_for_lines_dates = $factureRec->fields[
'rule_for_lines_dates'][
'arrayofkeyval'];
5512 if (empty($this->cache_rule_for_lines_dates)) {
5531 $num = count($this->cache_availability);
5538 $this->cache_availability = array();
5540 $langs->load(
'propal');
5542 $sql =
"SELECT rowid, code, label, position";
5543 $sql .=
" FROM " . $this->db->prefix() .
'c_availability';
5544 $sql .=
" WHERE active > 0";
5546 $resql = $this->db->query($sql);
5548 $num = $this->db->num_rows($resql);
5551 $obj = $this->db->fetch_object($resql);
5554 $label = ($langs->trans(
"AvailabilityType" . $obj->code) !=
"AvailabilityType" . $obj->code ? $langs->trans(
"AvailabilityType" . $obj->code) : ($obj->label !=
'-' ? $obj->label :
''));
5555 $this->cache_availability[$obj->rowid][
'code'] = (string) $obj->code;
5556 $this->cache_availability[$obj->rowid][
'label'] = (string) $label;
5557 $this->cache_availability[$obj->rowid][
'position'] = (int) $obj->position;
5562 $this->cache_availability =
dol_sort_array($this->cache_availability,
'position',
'asc', 0, 0, 1);
5566 dol_print_error($this->db);
5582 public function selectAvailabilityDelay($selected =
'', $htmlname =
'availid', $filtertype =
'', $addempty = 0, $morecss =
'', $noouput = 0)
5584 global $langs, $user;
5586 $this->load_cache_availability();
5588 dol_syslog(__METHOD__ .
" selected=" . $selected .
", htmlname=" . $htmlname, LOG_DEBUG);
5590 $out =
'<select id="' . $htmlname .
'" class="flat' . ($morecss ?
' ' . $morecss :
'') .
'" name="' . $htmlname .
'">';
5592 $out .=
'<option value="-1">'.(is_numeric($addempty) ?
' ' : $langs->trans($addempty)).
'</option>';
5594 foreach ($this->cache_availability as
$id => $arrayavailability) {
5595 if ($selected ==
$id) {
5596 $out .=
'<option value="' .
$id .
'" selected>';
5598 $out .=
'<option value="' .
$id .
'">';
5601 $out .=
'</option>';
5603 $out .=
'</select>';
5605 $out .=
info_admin($langs->trans(
"YouCanChangeValuesForThisListFromDictionarySetup"), 1);
5622 public function loadCacheInputReason()
5626 $num = count($this->cache_demand_reason);
5631 $sql =
"SELECT rowid, code, label";
5632 $sql .=
" FROM " . $this->db->prefix() .
'c_input_reason';
5633 $sql .=
" WHERE active > 0";
5635 $resql = $this->db->query($sql);
5637 $num = $this->db->num_rows($resql);
5640 $tmparray = array();
5642 $obj = $this->db->fetch_object($resql);
5645 $label = ($obj->label !=
'-' ? (string) $obj->label :
'');
5646 if ($langs->trans(
"DemandReasonType" . $obj->code) !=
"DemandReasonType" . $obj->code) {
5647 $label = $langs->trans(
"DemandReasonType" . $obj->code);
5649 if ($langs->trans($obj->code) != $obj->code) {
5650 $label = $langs->trans($obj->code);
5653 $tmparray[(int) $obj->rowid]
5655 'id' => (
int) $obj->rowid,
5656 'code' => (string) $obj->code,
5662 $this->cache_demand_reason =
dol_sort_array($tmparray,
'label',
'asc', 0, 0, 1);
5667 dol_print_error($this->db);
5684 public function selectInputReason($selected =
'', $htmlname =
'demandreasonid', $exclude =
'', $addempty = 0, $morecss =
'', $notooltip = 0)
5686 global $langs, $user;
5688 $this->loadCacheInputReason();
5690 print
'<select class="flat' . ($morecss ?
' ' . $morecss :
'') .
'" id="select_' . $htmlname .
'" name="' . $htmlname .
'">';
5692 print
'<option value="0"' . (empty($selected) ?
' selected' :
'') .
'> </option>';
5694 foreach ($this->cache_demand_reason as
$id => $arraydemandreason) {
5695 if ($arraydemandreason[
'code'] == $exclude) {
5699 if ($selected && ($selected == $arraydemandreason[
'id'] || $selected == $arraydemandreason[
'code'])) {
5700 print
'<option value="' . $arraydemandreason[
'id'] .
'" selected>';
5702 print
'<option value="' . $arraydemandreason[
'id'] .
'">';
5704 $label = $arraydemandreason[
'label'];
5705 print $langs->trans($label);
5709 if ($user->admin && empty($notooltip)) {
5710 print
info_admin($langs->trans(
"YouCanChangeValuesForThisListFromDictionarySetup"), 1);
5725 global $langs, $hookmanager;
5727 $num = count($this->cache_types_paiements);
5734 $this->cache_types_paiements = array();
5736 $sql =
"SELECT id, code, libelle as label, type, entity, active";
5737 $sql .=
" FROM " . $this->db->prefix() .
"c_paiement";
5738 $sql .=
" WHERE entity IN (" .
getEntity(
'c_paiement') .
")";
5740 $resql = $this->db->query($sql);
5742 $num = $this->db->num_rows($resql);
5745 $obj = $this->db->fetch_object($resql);
5748 $label = ($langs->transnoentitiesnoconv(
"PaymentTypeShort" . $obj->code) !=
"PaymentTypeShort" . $obj->code ? $langs->transnoentitiesnoconv(
"PaymentTypeShort" . $obj->code) : ($obj->label !=
'-' ? $obj->label :
''));
5749 $shortlabel = $label;
5751 $this->cache_types_paiements[(int) $obj->id][
'id'] = (
int) $obj->id;
5752 $this->cache_types_paiements[(int) $obj->id][
'code'] = (
string) $obj->code;
5753 $this->cache_types_paiements[(int) $obj->id][
'label'] = (
string) $label;
5754 $this->cache_types_paiements[(int) $obj->id][
'shortlabel'] = (
string) $shortlabel;
5755 $this->cache_types_paiements[(int) $obj->id][
'type'] = (
int) $obj->type;
5756 $this->cache_types_paiements[(int) $obj->id][
'entity'] = (
int) $obj->entity;
5757 $this->cache_types_paiements[(int) $obj->id][
'active'] = (
int) $obj->active;
5761 $parameters = array(
'dictionary' =>
'paymenttype');
5762 $reshook = $hookmanager->executeHooks(
'loadDictionaryCache', $parameters, $this);
5763 if (empty($reshook)) {
5764 if (is_array($hookmanager->resArray) && count($hookmanager->resArray)) {
5765 $this->cache_types_paiements = array_merge($this->cache_types_paiements, $hookmanager->resArray);
5768 $this->cache_types_paiements = $hookmanager->resArray;
5771 $this->cache_types_paiements =
dol_sort_array($this->cache_types_paiements,
'label',
'asc', 0, 0, 1);
5775 dol_print_error($this->db);
5801 public function select_conditions_paiements($selected = 0, $htmlname =
'condid', $filtertype = -1, $addempty = 0, $noinfoadmin = 0, $morecss =
'', $deposit_percent = -1, $noprint = 0)
5804 $out = $this->getSelectConditionsPaiements($selected, $htmlname, $filtertype, $addempty, $noinfoadmin, $morecss, $deposit_percent);
5805 if (empty($noprint)) {
5829 public function getSelectConditionsPaiements($selected = 0, $htmlname =
'condid', $filtertype = -1, $addempty = 0, $noinfoadmin = 0, $morecss =
'', $deposit_percent = -1)
5831 global $langs, $user;
5834 dol_syslog(__METHOD__ .
" selected=" . $selected .
", htmlname=" . $htmlname, LOG_DEBUG);
5836 $this->load_cache_conditions_paiements();
5839 if (empty($selected) && strpos($htmlname,
'search_') !== 0 &&
getDolGlobalInt(
'MAIN_DEFAULT_PAYMENT_TERM_ID')) {
5840 dol_syslog(__METHOD__ .
"Using deprecated option MAIN_DEFAULT_PAYMENT_TERM_ID", LOG_NOTICE);
5844 $out .=
'<select id="' . $htmlname .
'" class="flat selectpaymentterms' . ($morecss ?
' ' . $morecss :
'') .
'" name="' . $htmlname .
'">';
5846 $out .=
'<option value="0"> </option>';
5849 $selectedDepositPercent =
null;
5851 foreach ($this->cache_conditions_paiements as
$id => $arrayconditions) {
5852 if ($filtertype <= 0 && !empty($arrayconditions[
'deposit_percent'])) {
5856 if ($selected ==
$id) {
5857 $selectedDepositPercent = $deposit_percent > 0 ? $deposit_percent : $arrayconditions[
'deposit_percent'];
5858 $out .=
'<option value="' .
$id .
'" data-deposit_percent="' . $arrayconditions[
'deposit_percent'] .
'" selected>';
5860 $out .=
'<option value="' .
$id .
'" data-deposit_percent="' . $arrayconditions[
'deposit_percent'] .
'">';
5862 $label = $arrayconditions[
'label'];
5864 if (!empty($arrayconditions[
'deposit_percent'])) {
5865 $label = str_replace(
'__DEPOSIT_PERCENT__', $deposit_percent > 0 ? $deposit_percent : $arrayconditions[
'deposit_percent'], $label);
5869 $out .=
'</option>';
5871 $out .=
'</select>';
5872 if ($user->admin && empty($noinfoadmin)) {
5873 $out .=
info_admin($langs->trans(
"YouCanChangeValuesForThisListFromDictionarySetup"), 1);
5877 if ($deposit_percent >= 0) {
5878 $out .=
' <span id="' . $htmlname .
'_deposit_percent_container"' . (empty($selectedDepositPercent) ?
' style="display: none"' :
'') .
'>';
5879 $out .= $langs->trans(
'DepositPercent') .
' : ';
5880 $out .=
'<input id="' . $htmlname .
'_deposit_percent" name="' . $htmlname .
'_deposit_percent" class="maxwidth50" value="' . $deposit_percent .
'" />';
5883 <script nonce="' .
getNonce() .
'">
5884 $(document).ready(function () {
5885 let $select = $("#' . $htmlname .
'");
5886 let $container = $("#' . $htmlname .
'_deposit_percent_container");
5887 let $input = $("#' . $htmlname .
'_deposit_percent");
5889 function refreshDepositPercent(isInit) {
5890 let depositPercent = $select.find("option:selected").attr("data-deposit_percent") || "";
5892 if (depositPercent.length > 0) {
5894 // On page load, keep an existing (possibly customized) value; on user change use the payment term default
5895 if (!isInit || !parseFloat($input.val())) {
5896 $input.val(depositPercent);
5903 $select.change(function () {
5904 refreshDepositPercent(false);
5908 // Initialize on load so a default payment term with a deposit is reflected without a manual change
5909 refreshDepositPercent(true);
5932 $this->load_cache_rule_for_lines_dates();
5934 $out .=
'<select id="' . $htmlname .
'" class="flat selectbillingterm" name="' . $htmlname .
'">';
5936 $out .=
'<option value="-1"> </option>';
5940 foreach ($this->cache_rule_for_lines_dates as $rule_for_lines_dates_key => $rule_for_lines_dates_name) {
5941 if ($selected == $rule_for_lines_dates_key) {
5942 $out .=
'<option value="' . $rule_for_lines_dates_key .
'" selected>';
5944 $out .=
'<option value="' . $rule_for_lines_dates_key .
'">';
5947 $out .= $langs->trans($rule_for_lines_dates_name);
5948 $out .=
'</option>';
5950 $out .=
'</select>';
5976 public function select_types_paiements($selected =
'', $htmlname =
'paiementtype', $filtertype =
'', $format = 0, $empty = 1, $noadmininfo = 0, $maxlength = 0, $active = 1, $morecss =
'', $nooutput = 0)
5979 global $langs, $user;
5983 dol_syslog(__METHOD__ .
" " . $selected .
", " . $htmlname .
", " . $filtertype .
", " . $format, LOG_DEBUG);
5985 $filterarray = array();
5986 if ($filtertype ==
'CRDT') {
5987 $filterarray = array(0, 2, 3);
5988 } elseif ($filtertype ==
'DBIT') {
5989 $filterarray = array(1, 2, 3);
5990 } elseif ($filtertype !=
'' && $filtertype !=
'-1') {
5991 $filterarray = explode(
',', $filtertype);
5994 $this->load_cache_types_paiements();
5997 if (empty($selected) && strpos($htmlname,
'search_') !== 0 &&
getDolGlobalString(
'MAIN_DEFAULT_PAYMENT_TYPE_ID')) {
5998 dol_syslog(__METHOD__ .
"Using deprecated option MAIN_DEFAULT_PAYMENT_TYPE_ID", LOG_NOTICE);
6002 $out .=
'<select id="select' . $htmlname .
'" class="flat selectpaymenttypes' . ($morecss ?
' ' . $morecss :
'') .
'" name="' . $htmlname .
'">';
6004 $out .=
'<option value=""> </option>';
6006 foreach ($this->cache_types_paiements as
$id => $arraytypes) {
6008 if ($active >= 0 && $arraytypes[
'active'] != $active) {
6013 if (count($filterarray) && !in_array($arraytypes[
'type'], $filterarray)) {
6018 if ($empty && empty($arraytypes[
'code'])) {
6023 $out .=
'<option value="' .
$id .
'" data-code="'.$arraytypes[
'code'].
'"';
6024 } elseif ($format == 1) {
6025 $out .=
'<option value="' . $arraytypes[
'code'] .
'"';
6026 } elseif ($format == 2) {
6027 $out .=
'<option value="' . $arraytypes[
'code'] .
'"';
6028 } elseif ($format == 3) {
6029 $out .=
'<option value="' .
$id .
'"';
6032 if ($format == 1 || $format == 2) {
6033 if ($selected == $arraytypes[
'code']) {
6034 $out .=
' selected';
6037 if ($selected ==
$id) {
6038 $out .=
' selected';
6044 $value = ($maxlength ?
dol_trunc($arraytypes[
'label'], $maxlength) : $arraytypes[
'label']);
6045 } elseif ($format == 1) {
6046 $value = $arraytypes[
'code'];
6047 } elseif ($format == 2) {
6048 $value = ($maxlength ?
dol_trunc($arraytypes[
'label'], $maxlength) : $arraytypes[
'label']);
6049 } elseif ($format == 3) {
6050 $value = $arraytypes[
'code'];
6052 $out .= $value ? $value :
' ';
6053 $out .=
'</option>';
6055 $out .=
'</select>';
6056 if ($user->admin && !$noadmininfo) {
6057 $out .=
info_admin($langs->trans(
"YouCanChangeValuesForThisListFromDictionarySetup"), 1);
6061 if (empty($nooutput)) {
6081 $return =
'<select class="flat maxwidth100" id="select_' . $htmlname .
'" name="' . $htmlname .
'">';
6083 'HT' => $langs->trans(
"HT"),
6084 'TTC' => $langs->trans(
"TTC")
6086 foreach ($options as
$id => $value) {
6087 if ($selected ==
$id) {
6088 $return .=
'<option value="' .
$id .
'" selected>' . $value;
6090 $return .=
'<option value="' .
$id .
'">' . $value;
6092 $return .=
'</option>';
6094 $return .=
'</select>';
6114 $num = count($this->cache_transport_mode);
6121 $this->cache_transport_mode = array();
6123 $sql =
"SELECT rowid, code, label, active";
6124 $sql .=
" FROM " . $this->db->prefix() .
"c_transport_mode";
6125 $sql .=
" WHERE entity IN (" .
getEntity(
'c_transport_mode') .
")";
6127 $resql = $this->db->query($sql);
6129 $num = $this->db->num_rows($resql);
6132 $obj = $this->db->fetch_object($resql);
6135 $label = ($langs->transnoentitiesnoconv(
"PaymentTypeShort" . $obj->code) !=
"PaymentTypeShort" . $obj->code ? $langs->transnoentitiesnoconv(
"PaymentTypeShort" . $obj->code) : ($obj->label !=
'-' ? $obj->label :
''));
6136 $this->cache_transport_mode[(int) $obj->rowid]
6138 'rowid' => (
int) $obj->rowid,
6139 'code' => (string) $obj->code,
6140 'label' => (
string) $label,
6141 'active' => (int) $obj->active,
6146 $this->cache_transport_mode =
dol_sort_array($this->cache_transport_mode,
'label',
'asc', 0, 0, 1);
6150 dol_print_error($this->db);
6168 public function selectTransportMode($selected =
'', $htmlname =
'transportmode', $format = 0, $empty = 1, $noadmininfo = 0, $maxlength = 0, $active = 1, $morecss =
'')
6170 global $langs, $user;
6172 dol_syslog(__METHOD__ .
" " . $selected .
", " . $htmlname .
", " . $format, LOG_DEBUG);
6174 $this->load_cache_transport_mode();
6176 print
'<select id="select' . $htmlname .
'" class="flat selectmodetransport' . ($morecss ?
' ' . $morecss :
'') .
'" name="' . $htmlname .
'">';
6178 print
'<option value=""> </option>';
6180 foreach ($this->cache_transport_mode as
$id => $arraytypes) {
6182 if ($active >= 0 && $arraytypes[
'active'] != $active) {
6187 if ($empty && empty($arraytypes[
'code'])) {
6192 print
'<option value="' .
$id .
'"';
6193 } elseif ($format == 1) {
6194 print
'<option value="' . $arraytypes[
'code'] .
'"';
6195 } elseif ($format == 2) {
6196 print
'<option value="' . $arraytypes[
'code'] .
'"';
6197 } elseif ($format == 3) {
6198 print
'<option value="' .
$id .
'"';
6201 if (preg_match(
'/[a-z]/i', $selected) && $selected == $arraytypes[
'code']) {
6203 } elseif ($selected ==
$id) {
6209 $value = ($maxlength ?
dol_trunc($arraytypes[
'label'], $maxlength) : $arraytypes[
'label']);
6210 } elseif ($format == 1) {
6211 $value = $arraytypes[
'code'];
6212 } elseif ($format == 2) {
6213 $value = ($maxlength ?
dol_trunc($arraytypes[
'label'], $maxlength) : $arraytypes[
'label']);
6214 } elseif ($format == 3) {
6215 $value = $arraytypes[
'code'];
6217 print $value ? $value :
' ';
6224 if ($user->admin && !$noadmininfo) {
6225 print
info_admin($langs->trans(
"YouCanChangeValuesForThisListFromDictionarySetup"), 1);
6241 public function selectShippingMethod($selected =
'', $htmlname =
'shipping_method_id', $filtre =
'', $useempty = 0, $moreattrib =
'', $noinfoadmin = 0, $morecss =
'')
6243 global $langs, $user;
6245 $langs->loadLangs(array(
"admin",
"sendings"));
6247 $sql =
"SELECT rowid, code, libelle as label";
6248 $sql .=
" FROM " . $this->db->prefix() .
"c_shipment_mode";
6249 $sql .=
" WHERE active > 0";
6253 $sql .=
" ORDER BY libelle ASC";
6255 dol_syslog(get_class($this) .
"::selectShippingMode", LOG_DEBUG);
6257 $result = $this->db->query($sql);
6259 $num = $this->db->num_rows($result);
6262 print
'<select id="select' . $htmlname .
'" class="flat selectshippingmethod' . ($morecss ?
' ' . $morecss :
'') .
'" name="' . $htmlname .
'"' . ($moreattrib ?
' ' . $moreattrib :
'') .
'>';
6263 if ($useempty == 1 || ($useempty == 2 && $num > 1)) {
6264 print
'<option value="-1"> </option>';
6267 $obj = $this->db->fetch_object($result);
6268 if ($selected == $obj->rowid) {
6269 print
'<option value="' . $obj->rowid .
'" selected>';
6271 print
'<option value="' . $obj->rowid .
'">';
6273 print ($langs->trans(
"SendingMethod" . strtoupper($obj->code)) !=
"SendingMethod" . strtoupper($obj->code)) ? $langs->trans(
"SendingMethod" . strtoupper($obj->code)) : $obj->label;
6278 if ($user->admin && empty($noinfoadmin)) {
6279 print
info_admin($langs->trans(
"YouCanChangeValuesForThisListFromDictionarySetup"), 1);
6284 print $langs->trans(
"NoShippingMethodDefined");
6287 dol_print_error($this->db);
6304 $langs->load(
"sendings");
6306 if ($htmlname !=
"none") {
6307 print
'<form method="POST" action="' . $page .
'">';
6308 print
'<input type="hidden" name="action" value="setshippingmethod">';
6309 print
'<input type="hidden" name="token" value="' .
newToken() .
'">';
6310 $this->selectShippingMethod($selected, $htmlname,
'', $addempty);
6311 print
'<input type="submit" class="button valignmiddle" value="' . $langs->trans(
"Modify") .
'">';
6315 $code = $langs->getLabelFromKey($this->db, $selected,
'c_shipment_mode',
'rowid',
'code');
6316 print $langs->trans(
"SendingMethod" . strtoupper($code));
6335 $langs->load(
'bills');
6339 $sql =
"SELECT rowid, ref, situation_cycle_ref, situation_counter, situation_final, fk_soc";
6340 $sql .=
' FROM ' . $this->db->prefix() .
'facture';
6341 $sql .=
' WHERE entity IN (' .
getEntity(
'invoice') .
')';
6342 $sql .=
' AND situation_counter >= 1';
6343 $sql .=
' AND fk_soc = ' . (int) $socid;
6344 $sql .=
' AND type <> 2';
6345 $sql .=
' ORDER by situation_cycle_ref, situation_counter desc';
6346 $resql = $this->db->query($sql);
6348 $nbSituationInvoiceForThirdparty = 0;
6350 if ($resql && $this->db->num_rows($resql) > 0) {
6353 while ($obj = $this->db->fetch_object($resql)) {
6355 if ($obj->situation_cycle_ref != $ref) {
6357 $ref = $obj->situation_cycle_ref;
6359 if ($obj->situation_final != 1) {
6361 if (substr($obj->ref, 1, 4) !=
'PROV') {
6362 $nbSituationInvoiceForThirdparty++;
6364 if ($selected == $obj->rowid) {
6365 $opt .=
'<option value="' . $obj->rowid .
'" selected>' . $obj->ref .
'</option>';
6367 $opt .=
'<option value="' . $obj->rowid .
'">' . $obj->ref .
'</option>';
6374 dol_syslog(
"Error sql=" . $sql .
", error=" . $this->error, LOG_ERR);
6377 if ($nbSituationInvoiceForThirdparty > 0) {
6378 $opt =
'<option class="minwidth100" value="" selected> </option>'.$opt;
6380 $opt =
'<option class="minwidth100" value="-1" selected>'.$langs->trans(
'NoSituations').
'</option>';
6395 public function selectUnits($selected =
'', $htmlname =
'units', $showempty = 0, $unit_type =
'')
6399 $langs->load(
'products');
6401 $return =
'<select class="flat" id="' . $htmlname .
'" name="' . $htmlname .
'">';
6403 $sql =
"SELECT rowid, label, code FROM " . $this->db->prefix() .
"c_units";
6404 $sql .=
' WHERE active > 0';
6405 if (!empty($unit_type)) {
6406 $sql .=
" AND unit_type = '" . $this->db->escape($unit_type) .
"'";
6408 $sql .=
" ORDER BY sortorder";
6410 $resql = $this->db->query($sql);
6411 if ($resql && $this->db->num_rows($resql) > 0) {
6413 $return .=
'<option value="-1"></option>';
6416 while ($res = $this->db->fetch_object($resql)) {
6417 $unitLabel = $res->label;
6418 if (!empty($langs->tab_translate[
'unit' . $res->code])) {
6419 $unitLabel = $langs->trans(
'unit' . $res->code) != $res->label ? $langs->trans(
'unit' . $res->code) : $res->label;
6422 if ($selected == $res->rowid) {
6423 $return .=
'<option value="' . $res->rowid .
'" selected>' . $unitLabel .
'</option>';
6425 $return .=
'<option value="' . $res->rowid .
'">' . $unitLabel .
'</option>';
6428 $return .=
'</select>';
6452 public function select_comptes($selected =
'', $htmlname =
'accountid', $status = 0, $filtre =
'', $useempty = 0, $moreattrib =
'', $showcurrency = 0, $morecss =
'', $nooutput = 0, $addentrynone = 0)
6459 $langs->loadLangs(array(
"admin",
"banks"));
6462 $sql =
"SELECT rowid, label, bank, clos as status, currency_code";
6463 $sql .=
" FROM " . $this->db->prefix() .
"bank_account";
6464 $sql .=
" WHERE entity IN (" .
getEntity(
'bank_account') .
")";
6466 $sql .=
" AND clos = " . (int) $status;
6471 $sql .=
" ORDER BY label";
6473 dol_syslog(get_class($this) .
"::select_comptes", LOG_DEBUG);
6474 $result = $this->db->query($sql);
6476 $num = $this->db->num_rows($result);
6479 $out .=
'<select id="select' . $htmlname .
'" class="flat selectbankaccount' . ($morecss ?
' ' . $morecss :
'') .
'" name="' . $htmlname .
'"' . ($moreattrib ?
' ' . $moreattrib :
'') .
'>';
6483 $out .=
'<option class="opacitymedium" value="-1">' . $langs->trans(
"NoActiveBankAccountDefined") .
'</span>';
6485 $out .=
'<option class="opacitymedium" value="-1">' . $langs->trans(
"NoBankAccountDefined") .
'</span>';
6488 if (!empty($useempty) && !is_numeric($useempty)) {
6489 $out .=
'<option value="-1">'.$langs->trans($useempty).
'</option>';
6490 } elseif ($useempty == 1 || ($useempty == 2 && $num > 1)) {
6491 $out .=
'<option value="-1"> </option>';
6496 $obj = $this->db->fetch_object($result);
6498 $labeltoshow = trim($obj->label);
6499 $labeltoshowhtml = trim($obj->label);
6500 if ($showcurrency) {
6501 $labeltoshow .=
' (' . $obj->currency_code .
')';
6502 $labeltoshowhtml .=
' <span class="opacitymedium">(' . $obj->currency_code .
')</span>';
6504 if ($status == 2 && $obj->status == 1) {
6505 $labeltoshow .=
' (' . $langs->trans(
"Closed") .
')';
6506 $labeltoshowhtml .=
' <span class="opacitymedium">(' . $langs->trans(
"Closed") .
')</span>';
6509 if ($selected == $obj->rowid || ($useempty == 2 && $num == 1 && empty($selected))) {
6510 $out .=
'<option value="' . $obj->rowid .
'" data-currency-code="' . $obj->currency_code .
'" data-html="'.dolPrintHTMLForAttribute($labeltoshowhtml).
'" selected>';
6512 $out .=
'<option value="' . $obj->rowid .
'" data-currency-code="' . $obj->currency_code .
'" data-html="'.dolPrintHTMLForAttribute($labeltoshowhtml).
'">';
6514 $out .= $labeltoshow;
6515 $out .=
'</option>';
6519 if (!empty($addentrynone)) {
6520 $out .=
'<option value="-2"'.($selected == -2 ?
' selected="selected"' :
'').
' data-html="'.dolPrintHTMLForAttribute(
'<span class="opacitymedium">'.$langs->trans(
"None").
'</span>').
'">'.$langs->trans(
"None").
'</option>';
6523 $out .=
"</select>";
6526 dol_print_error($this->db);
6530 if (empty($nooutput)) {
6552 public function selectRib($selected =
'', $htmlname =
'ribcompanyid', $filtre =
'', $useempty = 0, $moreattrib =
'', $showibanbic = 0, $morecss =
'', $nooutput = 0)
6559 $langs->loadLangs(array(
"admin",
"banks"));
6562 $sql =
"SELECT rowid, label, bank, status, iban_prefix, bic, default_rib";
6563 $sql .=
" FROM " . $this->db->prefix() .
"societe_rib";
6564 $sql .=
" WHERE type = 'ban'";
6568 $sql .=
" ORDER BY label";
6569 dol_syslog(get_class($this) .
"::select_comptes", LOG_DEBUG);
6570 $result = $this->db->query($sql);
6572 $num = $this->db->num_rows($result);
6575 $out .=
'<select id="select' . $htmlname .
'" class="flat selectbankaccount' . ($morecss ?
' ' . $morecss :
'') .
'" name="' . $htmlname .
'"' . ($moreattrib ?
' ' . $moreattrib :
'') .
'>';
6578 $out .=
'<option class="opacitymedium" value="-1">' . $langs->trans(
"NoBankAccountDefined") .
'</span>';
6580 if (!empty($useempty) && !is_numeric($useempty)) {
6581 $out .=
'<option value="-1">'.$langs->trans($useempty).
'</option>';
6582 } elseif ($useempty == 1 || ($useempty == 2 && $num > 1)) {
6583 $out .=
'<option value="-1"> </option>';
6588 $obj = $this->db->fetch_object($result);
6590 if ($selected == $obj->rowid || ($useempty == 2 && $num == 1 && empty($selected))) {
6591 $out .=
'<option value="' . $obj->rowid .
'" data-iban-prefix="' . $iban .
' data-bic="' . $obj->bic .
'" selected>';
6593 $out .=
'<option value="' . $obj->rowid .
'" data-iban-prefix="' . $iban .
' data-bic="' . $obj->bic .
'">';
6595 $out .= trim($obj->label);
6597 $out .=
' (' . $iban .
'/' .$obj->bic.
')' . ($obj->default_rib ?
' ['.$langs->trans(
"ByDefault").
']' :
'');
6599 $out .=
'</option>';
6602 $out .=
"</select>";
6605 dol_print_error($this->db);
6609 if (empty($nooutput)) {
6629 public function selectEstablishments($selected =
'', $htmlname =
'entity', $status = 0, $filtre =
'', $useempty = 0, $moreattrib =
'')
6633 $langs->load(
"admin");
6636 $sql =
"SELECT rowid, name, fk_country, status, entity";
6637 $sql .=
" FROM " . $this->db->prefix() .
"establishment";
6638 $sql .=
" WHERE 1=1";
6640 $sql .=
" AND status = " . (int) $status;
6645 $sql .=
" ORDER BY name";
6647 dol_syslog(get_class($this) .
"::select_establishment", LOG_DEBUG);
6648 $result = $this->db->query($sql);
6650 $num = $this->db->num_rows($result);
6653 print
'<select id="select' . $htmlname .
'" class="flat selectestablishment" name="' . $htmlname .
'"' . ($moreattrib ?
' ' . $moreattrib :
'') .
'>';
6654 if ($useempty == 1 || ($useempty == 2 && $num > 1)) {
6655 print
'<option value="-1"> </option>';
6659 $obj = $this->db->fetch_object($result);
6660 if ($selected == $obj->rowid) {
6661 print
'<option value="' . $obj->rowid .
'" selected>';
6663 print
'<option value="' . $obj->rowid .
'">';
6665 print trim($obj->name);
6666 if ($status == 2 && $obj->status == 1) {
6667 print
' (' . $langs->trans(
"Closed") .
')';
6675 print
'<span class="opacitymedium">' . $langs->trans(
"NoActiveEstablishmentDefined") .
'</span>';
6677 print
'<span class="opacitymedium">' . $langs->trans(
"NoEstablishmentFound") .
'</span>';
6683 dol_print_error($this->db);
6700 if ($htmlname !=
"none") {
6701 print
'<form method="POST" action="' . $page .
'">';
6702 print
'<input type="hidden" name="action" value="setbankaccount">';
6703 print
'<input type="hidden" name="token" value="' .
newToken() .
'">';
6704 print img_picto(
'',
'bank_account',
'class="pictofixedwidth"');
6705 $nbaccountfound = $this->select_comptes($selected, $htmlname, 0,
'', $addempty);
6706 if ($nbaccountfound > 0) {
6707 print
'<input type="submit" class="button smallpaddingimp valignmiddle" value="' . $langs->trans(
"Modify") .
'">';
6711 $langs->load(
'banks');
6714 require_once DOL_DOCUMENT_ROOT .
'/compta/bank/class/account.class.php';
6715 $bankstatic =
new Account($this->db);
6716 $result = $bankstatic->fetch((
int) $selected);
6718 print $bankstatic->getNomUrl(1);
6737 public function formRib($page, $selected =
'', $htmlname =
'ribcompanyid', $filtre =
'', $addempty = 0, $showibanbic = 0)
6740 if ($htmlname !=
"none") {
6741 print
'<form method="POST" action="' . $page .
'">';
6742 print
'<input type="hidden" name="action" value="setbankaccountcustomer">';
6743 print
'<input type="hidden" name="token" value="' .
newToken() .
'">';
6744 $nbaccountfound = $this->selectRib($selected, $htmlname, $filtre, $addempty,
'', $showibanbic);
6745 if ($nbaccountfound > 0) {
6746 print
'<input type="submit" class="button smallpaddingimp valignmiddle" value="' . $langs->trans(
"Modify") .
'">';
6750 $langs->load(
'banks');
6753 require_once DOL_DOCUMENT_ROOT .
'/societe/class/companybankaccount.class.php';
6755 $result = $bankstatic->fetch((
int) $selected);
6757 print $bankstatic->label;
6759 print
' (' . $bankstatic->iban .
'/' .$bankstatic->bic.
')';
6783 $cate_arbo = $this->select_all_categories($categtype,
'',
'', 64, 0, 3);
6785 $arrayselected = array();
6787 $arrayselected =
GETPOST($htmlname,
'array:int');
6790 $cats =
$c->containing(
$object->id, $categtype);
6791 $arrayselected = array();
6792 foreach ($cats as $cat) {
6793 $arrayselected[] = $cat->id;
6797 $out .= img_picto(
'',
'category',
'class="pictofixedwidth"');
6798 $out .= $this->multiselectarray($htmlname, $cate_arbo, $arrayselected, 0, 0,
'minwidth100 widthcentpercentminusxx', 0, 0);
6802 $jsonclose =
'doJsCodeAfterPopupClose'.dol_sanitizeKeyCode($htmlname).
'()';
6803 $urltoopen =
'/categories/categorie_list.php?type='.urlencode($categtype).
'&nosearch=1';
6805 $s =
dolButtonToOpenUrlInDialogPopup($htmlname, $langs->transnoentitiesnoconv(
"Categories"), img_picto(
'',
'add',
'class="editfielda"'), $urltoopen,
'',
'',
'', $jsonclose);
6808 $out .=
'<!-- Add js code to open the popup for category/edit/add -->'.
"\n";
6809 $out .=
'<script>function doJsCodeAfterPopupClose'.dol_sanitizeKeyCode($htmlname).
'() {
6810 console.log("doJsCodeAfterPopupClose'.
dol_sanitizeKeyCode($htmlname).
' has been called, we refresh the combo content + refresh select2...");
6812 // Call an ajax to reload values and update the select
6815 url: \''.DOL_URL_ROOT.
'/core/ajax/fetchCategories.php\',
6817 action: \'getCategories\',
6822 success: function (data) {
6823 var $select = $(\'#'.dol_sanitizeKeyCode($htmlname).
'\');
6824 var selectedValues = $select.val();
6825 console.log(selectedValues);
6827 $.each(data,
function (index, item) {
6828 $select.append(\
'<option value="\' + item.id + \'" data-html="\' + item.htmlforattribute + \'">\' + item.htmlforoption + \'</option>\');
6830 $select.val(selectedValues);
6832 error: function (xhr, status, error) {
6833 console.log("Error when loading ajax page : " + error);
6837 // Refresh select2 to take account of new values (enough for small change)
6840 // Alternative if change in select is complex
6872 public function select_all_categories($type, $selected =
'', $htmlname =
"parent", $maxlength = 64, $fromid = 0, $outputmode = 0, $include = 0, $morecss =
'', $useempty = 1)
6877 include_once DOL_DOCUMENT_ROOT .
'/categories/class/categorie.class.php';
6881 if (is_numeric($type)) {
6882 $type = array_search($type, $cat->MAP_ID);
6885 $cate_arbo = $cat->get_full_arbo($type, $fromid, $include);
6887 $outarray = array();
6888 $outarrayrichhtml = array();
6891 $output =
'<select class="flat minwidth100' . ($morecss ?
' ' . $morecss :
'') .
'" name="' . $htmlname .
'" id="' . $htmlname .
'">';
6893 if (is_array($cate_arbo)) {
6894 $num = count($cate_arbo);
6897 $langs->load(
"categories");
6898 $output .=
'<option value="-1" disabled>' . $langs->trans(
"NoCategoriesDefined") .
'</option>';
6900 if ($useempty == 1 || ($useempty == 2 && $num > 1)) {
6901 $output .=
'<option value="-1"> </option>';
6903 foreach ($cate_arbo as $key => $value) {
6904 if ($cate_arbo[$key][
'id'] == $selected || ($selected ===
'auto' && count($cate_arbo) == 1)) {
6910 $labeltoshow = img_picto(
'',
'category',
'class="pictofixedwidth"'.(empty($cate_arbo[$key][
'color']) ?
'' :
' style="color: #' . $cate_arbo[$key][
'color'] .
'"'));
6911 $labeltoshow .=
dol_trunc($cate_arbo[$key][
'fulllabel'], $maxlength,
'middle');
6913 $outarray[$cate_arbo[$key][
'id']] = $cate_arbo[$key][
'fulllabel'];
6915 $outarrayrichhtml[$cate_arbo[$key][
'id']] = $labeltoshow;
6917 $output .=
'<option ' . $add .
'value="' . $cate_arbo[$key][
'id'] .
'"';
6926 $output .=
'</option>';
6928 $cate_arbo[$key][
'data-html'] = $labeltoshow;
6932 $output .=
'</select>';
6937 if ($outputmode == 2) {
6940 } elseif ($outputmode == 1) {
6942 } elseif ($outputmode == 3) {
6943 return $outarrayrichhtml;
6963 $html =
'<details class="dolibarr-help-block" style="margin-top:8px;">';
6964 $html .=
'<summary style="cursor:pointer; color:#0056b3; font-weight:normal; list-style:none; font-size:0.9em; display:flex; align-items:center;">';
6965 $html .=
'<span class="fa ' . $icon .
'" style="margin-right:6px;"></span>';
6966 $html .= $langs->trans(
"Help");
6967 $html .=
'</summary>';
6968 $html .=
'<div style="margin-top:6px; padding:10px; background:#f8f9fa; border:1px solid #dee2e6; border-radius:4px; font-size:0.9em; color:#555; line-height:1.5;">';
6971 $html .=
'</details>';
6996 public function form_confirm($page, $title, $question, $action, $formquestion = array(), $selectedchoice =
"", $useajax = 0, $height = 170, $width = 500)
6999 dol_syslog(__METHOD__ .
': using form_confirm is deprecated. Use formconfim instead.', LOG_WARNING);
7000 print $this->formconfirm($page, $title, $question, $action, $formquestion, $selectedchoice, $useajax, $height, $width);
7032 public function formconfirm($page, $title, $question, $action, $formquestion =
'', $selectedchoice =
'', $useajax = 0, $height = 0, $width = 600, $disableformtag = 0, $labelbuttonyes =
'Yes', $labelbuttonno =
'No', $helpContent =
'')
7034 global $langs,
$conf;
7037 $formconfirm =
'<!-- formconfirm - before call, page=' .
dol_escape_htmltag($page) .
' -->';
7043 $newselectedchoice = empty($selectedchoice) ?
"no" : $selectedchoice;
7044 if (
$conf->browser->layout ==
'phone') {
7049 if (empty($height)) {
7051 if (is_array($formquestion)) {
7052 $height += (count($formquestion) * 40);
7059 if (is_array($formquestion) && !empty($formquestion)) {
7061 foreach ($formquestion as $key => $input) {
7062 if (is_array($input) && !empty($input)) {
7063 if ($input[
'type'] ==
'hidden') {
7064 $moreattr = (!empty($input[
'moreattr']) ?
' ' . $input[
'moreattr'] :
'');
7065 $morecss = (!empty($input[
'morecss']) ?
' ' . $input[
'morecss'] :
'');
7073 $moreonecolumn =
'';
7074 $more .=
'<div class="tagtable paddingtopbottomonly centpercent noborderspacing">' .
"\n";
7075 foreach ($formquestion as $key => $input) {
7076 if (is_array($input) && !empty($input)) {
7077 $size = (!empty($input[
'size']) ?
' size="' . $input[
'size'] .
'"' :
'');
7078 $moreattr = (!empty($input[
'moreattr']) ?
' ' . $input[
'moreattr'] :
'');
7079 $morecss = (!empty($input[
'morecss']) ?
' ' . $input[
'morecss'] :
'');
7081 if ($input[
'type'] ==
'text' || $input[
'type'] ==
'input') {
7082 $more .=
'<div class="tagtr"><div class="tagtd' . (empty($input[
'tdclass']) ?
'' : (
' ' . $input[
'tdclass'])) .
'">' . ($input[
'label'] ??
'') .
'</div><div class="tagtd"><input type="text" class="flat' . $morecss .
'" id="' .
dol_escape_htmltag($input[
'name']) .
'" name="' .
dol_escape_htmltag($input[
'name']) .
'"' . $size .
' value="' . (empty($input[
'value']) ?
'' : $input[
'value']) .
'"' . $moreattr .
' spellcheck="false" /></div></div>' .
"\n";
7083 } elseif ($input[
'type'] ==
'password') {
7084 $more .=
'<div class="tagtr"><div class="tagtd' . (empty($input[
'tdclass']) ?
'' : (
' ' . $input[
'tdclass'])) .
'">' . ($input[
'label'] ??
'') .
'</div><div class="tagtd"><input type="password" class="flat' . $morecss .
'" id="' .
dol_escape_htmltag($input[
'name']) .
'" name="' .
dol_escape_htmltag($input[
'name']) .
'"' . $size .
' value="' . (empty($input[
'value']) ?
'' : $input[
'value']) .
'"' . $moreattr .
' /></div></div>' .
"\n";
7085 } elseif ($input[
'type'] ==
'textarea') {
7086 $moreonecolumn .=
'<div class="margintoponly">';
7087 $moreonecolumn .= ($input[
'label'] ??
'') .
'<br>';
7089 $moreonecolumn .= $input[
'value'] ??
'';
7090 $moreonecolumn .=
'</textarea>';
7091 $moreonecolumn .=
'</div>';
7092 } elseif (in_array($input[
'type'], [
'select',
'multiselect'])) {
7093 if (empty($morecss)) {
7094 $morecss =
'minwidth100';
7097 $show_empty = isset($input[
'select_show_empty']) ? $input[
'select_show_empty'] : 1;
7098 $key_in_label = isset($input[
'select_key_in_label']) ? $input[
'select_key_in_label'] : 0;
7099 $value_as_key = isset($input[
'select_value_as_key']) ? $input[
'select_value_as_key'] : 0;
7100 $translate = isset($input[
'select_translate']) ? $input[
'select_translate'] : 0;
7101 $maxlen = isset($input[
'select_maxlen']) ? $input[
'select_maxlen'] : 0;
7102 $disabled = isset($input[
'select_disabled']) ? $input[
'select_disabled'] : 0;
7103 $sort = isset($input[
'select_sort']) ? $input[
'select_sort'] :
'';
7105 $more .=
'<div class="tagtr"><div class="tagtd' . (empty($input[
'tdclass']) ?
'' : (
' ' . $input[
'tdclass'])) .
'">';
7106 if (!empty($input[
'label'])) {
7107 $more .= $input[
'label'] .
'</div><div class="tagtd left">';
7109 if ($input[
'type'] ==
'select') {
7110 $more .= $this->selectarray($input[
'name'], $input[
'values'], isset($input[
'default']) ? $input[
'default'] :
'-1', $show_empty, $key_in_label, $value_as_key, $moreattr, $translate, $maxlen, $disabled, $sort, $morecss);
7112 $more .= $this->multiselectarray($input[
'name'], $input[
'values'], is_array($input[
'default']) ? $input[
'default'] : [$input[
'default']], $key_in_label, $value_as_key, $morecss, $translate, $maxlen, $moreattr);
7114 $more .=
'</div></div>' .
"\n";
7115 } elseif ($input[
'type'] ==
'checkbox') {
7116 $more .=
'<div class="tagtr">';
7117 $more .=
'<div class="tagtd' . (empty($input[
'tdclass']) ?
'' : (
' ' . $input[
'tdclass'])) .
'"><label for="' .
dol_escape_htmltag($input[
'name']) .
'">' . $input[
'label'] .
'</label></div><div class="tagtd">';
7118 $more .=
'<input type="checkbox" class="flat' . ($morecss ?
' ' . $morecss :
'') .
'" id="' .
dol_escape_htmltag($input[
'name']) .
'" name="' .
dol_escape_htmltag($input[
'name']) .
'"' . $moreattr;
7119 if (isset($input[
'value']) && !is_bool($input[
'value']) && $input[
'value'] !=
'false' && $input[
'value'] !=
'0' && $input[
'value'] !=
'') {
7120 $more .=
' checked';
7122 if (isset($input[
'value']) && is_bool($input[
'value']) && $input[
'value']) {
7123 $more .=
' checked';
7125 if (isset($input[
'disabled'])) {
7126 $more .=
' disabled';
7128 $more .=
' /></div>';
7129 $more .=
'</div>' .
"\n";
7130 } elseif ($input[
'type'] ==
'radio') {
7132 foreach ($input[
'values'] as $selkey => $selval) {
7133 $more .=
'<div class="tagtr">';
7134 if (isset($input[
'label'])) {
7136 $more .=
'<div class="tagtd' . (empty($input[
'tdclass']) ?
' tdtop' : (
' tdtop ' . $input[
'tdclass'])) .
'">' . $input[
'label'] .
'</div>';
7138 $more .=
'<div class="tagtd' . (empty($input[
'tdclass']) ?
'' : (
' "' . $input[
'tdclass'])) .
'"> </div>';
7141 $more .=
'<div class="tagtd' . ($i == 0 ?
' tdtop' :
'') .
'"><input type="radio" class="flat' . $morecss .
'" id="' .
dol_escape_htmltag($input[
'name'] . $selkey) .
'" name="' .
dol_escape_htmltag($input[
'name']) .
'" value="' . $selkey .
'"' . $moreattr;
7142 if (!empty($input[
'disabled'])) {
7143 $more .=
' disabled';
7145 if (isset($input[
'default']) && $input[
'default'] === $selkey) {
7146 $more .=
' checked="checked"';
7149 $more .=
'<label for="' .
dol_escape_htmltag($input[
'name'] . $selkey) .
'" class="valignmiddle">' . $selval .
'</label>';
7150 $more .=
'</div></div>' .
"\n";
7153 } elseif ($input[
'type'] ==
'date' || $input[
'type'] ==
'datetime') {
7154 $more .=
'<div class="tagtr"><div class="tagtd' . (empty($input[
'tdclass']) ?
'' : (
' ' . $input[
'tdclass'])) .
'">' . $input[
'label'] .
'</div>';
7155 $more .=
'<div class="tagtd">';
7156 $addnowlink = (empty($input[
'datenow']) ? 0 : 1);
7158 if ($input[
'type'] ==
'datetime') {
7159 $h = isset($input[
'hours']) ? $input[
'hours'] : 1;
7160 $m = isset($input[
'minutes']) ? $input[
'minutes'] : 1;
7162 $more .= $this->selectDate(isset($input[
'value']) ? $input[
'value'] : -1, $input[
'name'], $h, $m, 0,
'', 1, $addnowlink);
7163 $more .=
'</div></div>'.
"\n";
7164 $formquestion[] = array(
'name' => $input[
'name'].
'day');
7165 $formquestion[] = array(
'name' => $input[
'name'].
'month');
7166 $formquestion[] = array(
'name' => $input[
'name'].
'year');
7167 $formquestion[] = array(
'name' => $input[
'name'].
'hour');
7168 $formquestion[] = array(
'name' => $input[
'name'].
'min');
7169 } elseif ($input[
'type'] ==
'other') {
7170 $more .=
'<div class="tagtr"><div class="tagtd'.(empty($input[
'tdclass']) ?
'' : (
' '.$input[
'tdclass'])).
'">';
7171 if (!empty($input[
'label'])) {
7172 $more .= $input[
'label'] .
'</div><div class="tagtd">';
7174 if (!empty($input[
'value'])) {
7175 $more .= $input[
'value'];
7177 $more .=
'</div></div>' .
"\n";
7178 } elseif ($input[
'type'] ==
'onecolumn') {
7179 $moreonecolumn .=
'<div class="margintoponly">';
7180 $moreonecolumn .= $input[
'value'] ??
'';
7181 $moreonecolumn .=
'</div>' .
"\n";
7182 } elseif ($input[
'type'] ==
'hidden') {
7184 } elseif ($input[
'type'] ==
'separator') {
7187 $more .=
'Error type ' . $input[
'type'] .
' for the confirm box is not a supported type';
7191 $more .=
'</div>' .
"\n";
7192 $more .= $moreonecolumn;
7198 if (!empty(
$conf->dol_use_jmobile)) {
7201 if (empty(
$conf->use_javascript_ajax)) {
7207 $dialogconfirm =
'dialog-confirm';
7209 if (!is_numeric($useajax)) {
7213 $dialogconfirm .=
'-' . $button;
7215 $pageyes = $page . (preg_match(
'/\?/', $page) ?
'&' :
'?') .
'action=' . urlencode($action) .
'&confirm=yes';
7216 $pageno = ($useajax == 2 ? $page . (preg_match(
'/\?/', $page) ?
'&' :
'?') .
'action=' . urlencode($action) .
'&confirm=no' :
'');
7219 if (is_array($formquestion)) {
7220 foreach ($formquestion as $key => $input) {
7223 if (is_array($input) && isset($input[
'name'])) {
7224 if (strpos($input[
'name'],
',') > 0) {
7225 $inputok = array_merge($inputok, explode(
',', $input[
'name']));
7227 array_push($inputok, $input[
'name']);
7232 if (is_array($input) && isset($input[
'inputko']) && $input[
'inputko'] == 1 && isset($input[
'name'])) {
7233 array_push($inputko, $input[
'name']);
7240 $formconfirm .=
'<div id="' . $dialogconfirm .
'" title="' .
dol_escape_htmltag($title) .
'" style="display: none;">';
7241 $formconfirm .=
'<div style="display: flex; flex-direction: column; height: 100%;">';
7242 if (is_array($formquestion) && array_key_exists(
'text', $formquestion) && !empty($formquestion[
'text'])) {
7243 $formconfirm .=
'<div class="confirmtext">' . $formquestion[
'text'] .
'</div>' .
"\n";
7245 if (!empty($more)) {
7246 $formconfirm .=
'<div class="confirmquestions">' . $more .
'</div>' .
"\n";
7249 if (!empty($helpContent)) {
7250 $formconfirm .=
'<div style="text-align:left; margin-top:12px; padding-top:8px; border-top:1px solid #eee; clear:both;">';
7251 $formconfirm .= $this->getHelpBlock($helpContent);
7252 $formconfirm .=
'</div>';
7254 if (!empty($question)) {
7255 $formconfirm .=
'<div class="confirmmessage" style="padding-top: 15px;">';
7256 $formconfirm .= img_help(0,
'') .
' ' . $question;
7257 $formconfirm .=
'</div>';
7259 $formconfirm .=
'</div>';
7260 $formconfirm .=
'</div>' .
"\n";
7262 $formconfirm .=
"\n<!-- begin code of popup for formconfirm page=" . $page .
" -->\n";
7263 $formconfirm .=
'<script nonce="' .
getNonce() .
'" type="text/javascript">' .
"\n";
7264 $formconfirm .=
"/* Code for the jQuery('#dialogforpopup').dialog() */\n";
7265 $formconfirm .=
'jQuery(document).ready(function() {
7267 $( "#' . $dialogconfirm .
'" ).dialog({
7268 autoOpen: ' . ($autoOpen ?
"true" :
"false") .
',';
7269 if ($newselectedchoice ==
'no') {
7272 $(this).parent().find("button.ui-button:eq(2)").focus();
7277 if ($useajax == 1) {
7278 $jsforcursor =
'// The call to urljump can be slow, so we set the wait cursor' .
"\n";
7279 $jsforcursor .=
'jQuery("html,body,#id-container").addClass("cursorwait");' .
"\n";
7282 $postconfirmas =
'GET';
7283 $maxurllengthforget =
getDolGlobalInt(
'MAIN_MAX_URL_LENGTH_FOR_GET', 2000);
7290 closeOnEscape:
false,
7292 \
'' .
dol_escape_js($langs->transnoentities($labelbuttonyes)) .
'\':
function() {
7293 var options =
"token=' . urlencode(newToken()) . '";
7294 var inputok =
' . json_encode($inputok) . ';
7295 var page = \
'' .
dol_escape_js(!empty($page) ? $page :
'') .
'\';
7296 var pageyes = \
'' .
dol_escape_js(!empty($pageyes) ? $pageyes :
'') .
'\';
7298 if (inputok.length > 0) {
7299 $.each(inputok,
function(i, inputname) {
7302 if ($(
"input[name=\'" + inputname +
"\']").attr(
"type") ==
"radio") {
7303 inputvalue = $(
"input[name=\'" + inputname +
"\']:checked").val();
7305 if ($(
"#" + inputname).attr(
"type") ==
"checkbox") { more =
":checked"; }
7306 inputvalue = $(
"#" + inputname + more).val();
7308 if (typeof inputvalue ==
"undefined") { inputvalue=
""; }
7309 console.log(
"formconfirm check inputname="+inputname+
" inputvalue="+inputvalue);
7310 options +=
"&" + inputname +
"=" + encodeURIComponent(inputvalue);
7313 var urljump = pageyes + (pageyes.indexOf(
"?") < 0 ?
"?" :
"&") + options;
7314 if (pageyes.length > 0) {
';
7315 if ($postconfirmas == 'GET
') {
7316 $formconfirm .= 'dolSubmitConfirmForm(urljump, pageyes, options,
' . $maxurllengthforget . ');
';
7318 $formconfirm .= $jsforcursor;
7319 $formconfirm .= 'var post = $.post(
7322 function(data) { $(
"body").html(data); jQuery(
"html,body,#id-container").removeClass(
"cursorwait"); }
7326 console.log(
"after post ok");
7328 $(
this).dialog(
"close");
7330 \
'' .
dol_escape_js($langs->transnoentities($labelbuttonno)) .
'\':
function() {
7331 var options =
"token=' . urlencode(newToken()) . '";
7332 var inputko =
' . json_encode($inputko) . ';
7333 var page = \
'' .
dol_escape_js(!empty($page) ? $page :
'') .
'\';
7334 var pageno=\
'' .
dol_escape_js(!empty($pageno) ? $pageno :
'') .
'\';
7335 if (inputko.length > 0) {
7336 $.each(inputko,
function(i, inputname) {
7338 if ($(
"#" + inputname).attr(
"type") ==
"checkbox") { more =
":checked"; }
7339 var inputvalue = $(
"#" + inputname + more).val();
7340 if (typeof inputvalue ==
"undefined") { inputvalue=
""; }
7341 options +=
"&" + inputname +
"=" + encodeURIComponent(inputvalue);
7344 var urljump=pageno + (pageno.indexOf(
"?") < 0 ?
"?" :
"&") + options;
7346 if (pageno.length > 0) {
';
7347 if ($postconfirmas == 'GET
') {
7348 $formconfirm .= 'dolSubmitConfirmForm(urljump, pageno, options,
' . $maxurllengthforget . ');
';
7350 $formconfirm .= $jsforcursor;
7351 $formconfirm .= 'var post = $.post(
7354 function(data) { $(
"body").html(data); jQuery(
"html,body,#id-container").removeClass(
"cursorwait"); }
7358 console.log(
"after post ko");
7360 $(
this).dialog(
"close");
7366 var
button =
"' . $button . '";
7368 $(
"#" +
button ).click(
function() {
7369 $(
"#' . $dialogconfirm . '").dialog(
"open");
7375 $formconfirm .= "<!-- end ajax formconfirm -->\n";
7377 $formconfirm .= "\n<!-- begin formconfirm page=" . dol_escape_htmltag($page) . " -->\n";
7379 if (empty($disableformtag)) {
7380 $formconfirm .= '<form method=
"POST" action=
"' . $page . '" class=
"notoptoleftnoright">
' . "\n";
7383 $formconfirm .= '<input
type=
"hidden" name=
"action" value=
"' . $action . '">
' . "\n";
7384 $formconfirm .= '<input
type=
"hidden" name=
"token" value=
"' . newToken() . '">
' . "\n";
7386 $formconfirm .= '<div
class=
"valid">
' . "\n";
7389 $formconfirm .= '<div
class=
"validtitre">
';
7390 $formconfirm .= img_picto('', 'pictoconfirm
') . ' ' . $title;
7391 $formconfirm .= '</div>
' . "\n";
7394 if (is_array($formquestion) && array_key_exists('text
', $formquestion) && !empty($formquestion['text
'])) {
7395 $formconfirm .= '<div
class=
"valid">
' . $formquestion['text
'] . '</div>
' . "\n";
7400 $formconfirm .= '<div>
' . "\n";
7401 $formconfirm .= $more;
7402 $formconfirm .= '</div>
' . "\n";
7405 // NEW: Help block row (between form fields and question)
7406 if (!empty($helpContent)) {
7407 $formconfirm .= '<div style=
"padding-top:8px; border-top:1px solid #888;">
';
7408 $formconfirm .= $this->getHelpBlock($helpContent);
7409 $formconfirm .= '</div>
' . "\n";
7412 // Let's add a row that acts as a spacer.
7413 $formconfirm .=
'<div style="padding-top: 20px;"></div>' .
"\n";
7416 $formconfirm .=
'<div class="inline-block">' . $question .
'</div>';
7418 $formconfirm .=
'<div class="inline-block">';
7419 $formconfirm .= $this->selectyesno(
"confirm", $newselectedchoice, 0,
false, 0, 0,
'marginleftonly marginrightonly', $labelbuttonyes, $labelbuttonno);
7420 $formconfirm .=
'<input class="button valignmiddle confirmvalidatebutton small" type="submit" value="' . $langs->trans(
"Validate") .
'">';
7421 $formconfirm .=
'</div>';
7423 $formconfirm .=
'</div>';
7425 if (empty($disableformtag)) {
7426 $formconfirm .=
"</form>\n";
7428 $formconfirm .=
'<br>';
7430 if (!empty(
$conf->use_javascript_ajax)) {
7431 $formconfirm .=
'<!-- code to disable button to avoid double clic -->';
7432 $formconfirm .=
'<script nonce="' .
getNonce() .
'" type="text/javascript">' .
"\n";
7434 $(document).ready(function () {
7435 $(".confirmvalidatebutton").on("click", function() {
7436 console.log("We click on button confirmvalidatebutton");
7437 $(this).attr("disabled", "disabled");
7438 setTimeout(\'$(".confirmvalidatebutton").removeAttr("disabled")\', 3000);
7439 //console.log($(this).closest("form"));
7440 $(this).closest("form").submit();
7444 $formconfirm .=
'</script>' .
"\n";
7447 $formconfirm .=
"<!-- end formconfirm -->\n";
7450 return $formconfirm;
7471 public function form_project($page, $socid, $selected =
'', $htmlname =
'projectid', $discard_closed = 0, $maxlength = 20, $forcefocus = 0, $nooutput = 0, $textifnoproject =
'', $morecss =
'', $option =
'')
7476 require_once DOL_DOCUMENT_ROOT .
'/core/lib/project.lib.php';
7477 require_once DOL_DOCUMENT_ROOT .
'/core/class/html.formprojet.class.php';
7483 $langs->load(
"project");
7484 if ($htmlname !=
"none") {
7485 $out .=
'<form method="post" action="' . $page .
'">';
7486 $out .=
'<input type="hidden" name="action" value="classin">';
7487 $out .=
'<input type="hidden" name="token" value="' .
newToken() .
'">';
7488 $out .= $formproject->select_projects($socid, $selected, $htmlname, $maxlength, 0, 1, $discard_closed, $forcefocus, 0, 0,
'', 1, 0, $morecss);
7489 $out .=
'<input type="submit" class="button smallpaddingimp" value="' . $langs->trans(
"Modify") .
'">';
7492 $out .=
'<span class="project_head_block">';
7493 if ($selected instanceof
Project) {
7494 $out .= $selected->getNomUrl(0, $option, 1);
7495 } elseif (is_numeric($selected)) {
7496 $projet =
new Project($this->db);
7497 $projet->fetch((
int) $selected);
7498 $out .= $projet->getNomUrl(0, $option, 1);
7500 $out .=
'<span class="opacitymedium">' . $textifnoproject .
'</span>';
7505 if (empty($nooutput)) {
7529 public function form_conditions_reglement($page, $selected =
'', $htmlname =
'cond_reglement_id', $addempty = 0, $type =
'', $filtertype = -1, $deposit_percent = -1, $nooutput = 0)
7534 $selected = (int) $selected;
7538 if ($htmlname !=
"none") {
7539 $out .=
'<form method="POST" action="' . $page .
'">';
7540 $out .=
'<input type="hidden" name="action" value="setconditions">';
7541 $out .=
'<input type="hidden" name="token" value="' .
newToken() .
'">';
7543 $out .=
'<input type="hidden" name="type" value="' .
dol_escape_htmltag($type) .
'">';
7545 $out .= $this->getSelectConditionsPaiements($selected, $htmlname, $filtertype, $addempty, 0,
'', $deposit_percent);
7546 $out .=
'<input type="submit" class="button valignmiddle smallpaddingimp" value="' . $langs->trans(
"Modify") .
'">';
7550 $this->load_cache_conditions_paiements();
7552 if (isset($this->cache_conditions_paiements[$selected])) {
7553 $label = $this->cache_conditions_paiements[$selected][
'label'];
7555 if (!empty($this->cache_conditions_paiements[$selected][
'deposit_percent'])) {
7556 $label = str_replace(
'__DEPOSIT_PERCENT__', $deposit_percent > 0 ? $deposit_percent : $this->cache_conditions_paiements[$selected][
'deposit_percent'], $label);
7561 $langs->load(
'errors');
7562 $out .= $langs->trans(
'ErrorNotInDictionaryPaymentConditions', $selected);
7569 if (empty($nooutput)) {
7595 if ($htmlname !=
'none') {
7596 $out .=
'<form method="POST" action="' . $page .
'">';
7597 $out .=
'<input type="hidden" name="action" value="setruleforlinesdates">';
7598 $out .=
'<input type="hidden" name="token" value="' .
newToken() .
'">';
7599 $out .= $this->getSelectRuleForLinesDates($selected, $htmlname, $addempty);
7600 $out .=
'<input type="submit" class="button valignmiddle smallpaddingimp" value="' . $langs->trans(
"Modify") .
'">';
7603 if (isset($selected)) {
7604 $this->load_cache_rule_for_lines_dates();
7605 if (isset($this->cache_rule_for_lines_dates[$selected])) {
7606 $label = $this->cache_rule_for_lines_dates[$selected];
7607 $out .= $langs->trans($label);
7614 if (empty($nooutput)) {
7638 if ($htmlname !=
"none") {
7639 print
'<form method="post" action="' . $page .
'">';
7640 print
'<input type="hidden" name="action" value="setavailability">';
7641 print
'<input type="hidden" name="token" value="' .
newToken() .
'">';
7642 print $this->selectAvailabilityDelay($selected, $htmlname,
'', $addempty,
'', 1);
7643 print
'<input type="submit" name="modify" class="button smallpaddingimp" value="' . $langs->trans(
"Modify") .
'">';
7644 print
'<input type="submit" name="cancel" class="button smallpaddingimp" value="' . $langs->trans(
"Cancel") .
'">';
7648 $this->load_cache_availability();
7650 if (isset($this->cache_availability[$selected])) {
7651 print $this->cache_availability[$selected][
'label'];
7672 public function formInputReason($page, $selected =
'', $htmlname =
'demandreason', $addempty = 0, $morecss =
'')
7675 if ($htmlname !=
"none") {
7676 print
'<form method="post" action="' . $page .
'">';
7677 print
'<input type="hidden" name="action" value="setdemandreason">';
7678 print
'<input type="hidden" name="token" value="' .
newToken() .
'">';
7679 $this->selectInputReason($selected, $htmlname,
'-1', $addempty, $morecss);
7680 print
'<input type="submit" class="button smallpaddingimp" value="' . $langs->trans(
"Modify") .
'">';
7684 $this->loadCacheInputReason();
7685 foreach ($this->cache_demand_reason as $key => $val) {
7686 if ($val[
'id'] == $selected) {
7687 print $val[
'label'];
7712 public function form_date($page, $selected, $htmlname, $displayhour = 0, $displaymin = 0, $nooutput = 0, $type =
'')
7719 if ($htmlname !=
"none") {
7720 $ret .=
'<form method="POST" action="' . $page .
'" name="form' . $htmlname .
'">';
7721 $ret .=
'<input type="hidden" name="action" value="set' . $htmlname .
'">';
7722 $ret .=
'<input type="hidden" name="token" value="' .
newToken() .
'">';
7724 $ret .=
'<input type="hidden" name="type" value="' .
dol_escape_htmltag($type) .
'">';
7726 $ret .=
'<table class="nobordernopadding">';
7728 $ret .= $this->selectDate($selected, $htmlname, $displayhour, $displaymin, 1,
'form' . $htmlname, 1, 0);
7730 $ret .=
'<td class="left"><input type="submit" class="button smallpaddingimp" value="' . $langs->trans(
"Modify") .
'"></td>';
7731 $ret .=
'</tr></table></form>';
7740 if (empty($nooutput)) {
7759 public function form_users($page, $selected =
'', $htmlname =
'userid', $exclude = array(), $include = array())
7764 if ($htmlname !=
"none") {
7765 print
'<form method="POST" action="' . $page .
'" name="form' . $htmlname .
'">';
7766 print
'<input type="hidden" name="action" value="set' . $htmlname .
'">';
7767 print
'<input type="hidden" name="token" value="' .
newToken() .
'">';
7768 print $this->select_dolusers($selected, $htmlname, 1, $exclude, 0, $include);
7769 print
'<input type="submit" class="button smallpaddingimp valignmiddle" value="' . $langs->trans(
"Modify") .
'">';
7773 require_once DOL_DOCUMENT_ROOT .
'/user/class/user.class.php';
7774 $theuser =
new User($this->db);
7775 $theuser->fetch((
int) $selected);
7776 print $theuser->getNomUrl(1);
7800 public function form_modes_reglement($page, $selected =
'', $htmlname =
'mode_reglement_id', $filtertype =
'', $active = 1, $addempty = 0, $type =
'', $nooutput = 0, $short = 0)
7806 if ($htmlname !=
"none") {
7807 $out .=
'<form method="POST" action="' . $page .
'">';
7808 $out .=
'<input type="hidden" name="action" value="setmode">';
7809 $out .=
'<input type="hidden" name="token" value="' .
newToken() .
'">';
7811 $out .=
'<input type="hidden" name="type" value="' .
dol_escape_htmltag($type) .
'">';
7813 $out .= $this->select_types_paiements($selected, $htmlname, $filtertype, 0, $addempty, 0, 0, $active,
'', 1);
7814 $out .=
'<input type="submit" class="button smallpaddingimp valignmiddle" value="' . $langs->trans(
"Modify") .
'">';
7817 if ((
int) $selected) {
7818 $this->load_cache_types_paiements();
7820 $out .= $this->cache_types_paiements[(int) $selected][
'shortlabel'] ??
' ';
7822 $out .= $this->cache_types_paiements[(int) $selected][
'label'] ??
' ';
7850 if ($htmlname !=
"none") {
7851 print
'<form method="POST" action="' . $page .
'">';
7852 print
'<input type="hidden" name="action" value="settransportmode">';
7853 print
'<input type="hidden" name="token" value="' .
newToken() .
'">';
7854 $this->selectTransportMode($selected, $htmlname, 0, $addempty, 0, 0, $active);
7855 print
'<input type="submit" class="button smallpaddingimp valignmiddle" value="' . $langs->trans(
"Modify") .
'">';
7859 $this->load_cache_transport_mode();
7860 print $this->cache_transport_mode[$selected][
'label'];
7881 if ($htmlname !=
"none") {
7882 print
'<form method="POST" action="' . $page .
'">';
7883 print
'<input type="hidden" name="action" value="setmulticurrencycode">';
7884 print
'<input type="hidden" name="token" value="' .
newToken() .
'">';
7885 print $this->selectMultiCurrency($selected, $htmlname, 0);
7886 print
'<input type="submit" class="button smallpaddingimp valignmiddle" value="' . $langs->trans(
"Modify") .
'">';
7889 require_once DOL_DOCUMENT_ROOT .
'/core/lib/company.lib.php';
7890 print !empty($selected) ?
currency_name($selected, 1) :
' ';
7909 global $langs,
$conf;
7911 if ($htmlname !=
"none") {
7912 print
'<form method="POST" action="' . $page .
'">';
7913 print
'<input type="hidden" name="action" value="setmulticurrencyrate">';
7914 print
'<input type="hidden" name="token" value="' .
newToken() .
'">';
7915 print
'<input type="text" class="maxwidth75" name="' . $htmlname .
'" value="' . (!empty($rate) ?
price(
price2num($rate,
'CR')) : 1) .
'" spellcheck="false" /> ';
7916 print
'<select name="calculation_mode" id="calculation_mode">';
7917 print
'<option value="1">Change ' . $langs->trans(
"PriceUHT") .
' of lines</option>';
7918 print
'<option value="2">Change ' . $langs->trans(
"PriceUHTCurrency") .
' of lines</option>';
7921 print
'<input type="submit" class="button smallpaddingimp valignmiddle" value="' . $langs->trans(
"Modify") .
'">';
7924 if (!empty($rate)) {
7925 print
price($rate, 1, $langs, 0, 0);
7926 if ($currency && $rate != 1) {
7933 print
' <span class="opacitymedium">(' .
price($rate_direct, 1, $langs, 0, 0) .
' ' .
$conf->currency .
' = 1 ' . $currency .
')</span>';
7935 print
' <span class="opacitymedium">(' .
price($rate, 1, $langs, 0, 0) .
' ' . $currency .
' = 1 ' .
$conf->currency .
')</span>';
7963 public function form_remise_dispo($page, $selected, $htmlname, $socid, $amount, $filter =
'', $maxvalue = 0, $more =
'', $hidelist = 0, $discount_type = 0, $filterabsolutediscount = 0, $filtercreditnote = 0)
7966 global
$conf, $langs;
7968 if ($htmlname !=
"none") {
7969 print
'<form method="post" action="' . $page .
'" class="inline-block">';
7970 print
'<input type="hidden" name="action" value="setabsolutediscount">';
7971 print
'<input type="hidden" name="token" value="' .
newToken() .
'">';
7972 print
'<div class="inline-block">';
7973 if (!empty($discount_type)) {
7975 if (!$filter || $filter ==
"fk_invoice_supplier_source IS NULL") {
7976 $translationKey =
'HasAbsoluteDiscountFromSupplier';
7978 $translationKey =
'HasCreditNoteFromSupplier';
7981 if (!$filter || $filter ==
"fk_invoice_supplier_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')") {
7982 $translationKey =
'HasAbsoluteDiscountFromSupplier';
7984 $translationKey =
'HasCreditNoteFromSupplier';
7989 if (!$filter || $filter ==
"fk_facture_source IS NULL") {
7990 $translationKey =
'CompanyHasAbsoluteDiscount';
7992 $translationKey =
'CompanyHasCreditNote';
7995 if (!$filter || $filter ==
"fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')") {
7996 $translationKey =
'CompanyHasAbsoluteDiscount';
7998 $translationKey =
'CompanyHasCreditNote';
8002 print $langs->trans($translationKey,
price($amount, 0, $langs, 0, 0, -1,
$conf->currency));
8003 if (empty($hidelist)) {
8007 if (empty($hidelist)) {
8008 print
'<div class="inline-block" style="padding-right: 10px">';
8009 $newfilter =
'discount_type = ' . intval($discount_type);
8010 if (!empty($discount_type)) {
8011 $newfilter .=
' AND fk_invoice_supplier IS NULL AND fk_invoice_supplier_line IS NULL';
8013 $newfilter .=
' AND fk_facture IS NULL AND fk_facture_line IS NULL';
8016 $sanitizedfilter = $filter;
8017 $newfilter .=
' AND (' . $sanitizedfilter .
')';
8020 $nbqualifiedlines = $this->select_remises((
string) $selected, $htmlname, $newfilter, $socid, $maxvalue);
8021 if ($nbqualifiedlines > 0) {
8022 print
' <input type="submit" class="button smallpaddingimp" value="' .
dol_escape_htmltag($langs->trans(
"UseLine")) .
'"';
8023 if (!empty($discount_type) && $filter && $filter !=
"fk_invoice_supplier_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')") {
8024 print
' title="' . $langs->trans(
"UseCreditNoteInInvoicePayment") .
'"';
8026 if (empty($discount_type) && $filter && $filter !=
"fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')") {
8027 print
' title="' . $langs->trans(
"UseCreditNoteInInvoicePayment") .
'"';
8035 print
'<div class="inline-block">';
8061 public function form_contacts($page, $societe, $selected =
'', $htmlname =
'contactid')
8066 if ($htmlname !=
"none") {
8067 print
'<form method="post" action="' . $page .
'">';
8068 print
'<input type="hidden" name="action" value="set_contact">';
8069 print
'<input type="hidden" name="token" value="' .
newToken() .
'">';
8070 print
'<table class="nobordernopadding">';
8072 print $this->selectcontacts($societe->id, $selected, $htmlname);
8075 $addcontact = (
getDolGlobalString(
'SOCIETE_ADDRESSES_MANAGEMENT') ? $langs->trans(
"AddContact") : $langs->trans(
"AddContactAddress"));
8076 print
'<a href="' . DOL_URL_ROOT .
'/contact/card.php?socid=' . $societe->id .
'&action=create&backtoreferer=1">' . $addcontact .
'</a>';
8079 print
'<td class="left"><input type="submit" class="button smallpaddingimp" value="' . $langs->trans(
"Modify") .
'"></td>';
8080 print
'</tr></table></form>';
8083 require_once DOL_DOCUMENT_ROOT .
'/contact/class/contact.class.php';
8084 $contact =
new Contact($this->db);
8085 $contact->fetch((
int) $selected);
8086 print $contact->getFullName($langs);
8111 public function form_thirdparty($page, $selected =
'', $htmlname =
'socid', $filter =
'', $showempty = 0, $showtype = 0, $forcecombo = 0, $events = array(), $nooutput = 0, $excludeids = array(), $textifnothirdparty =
'')
8117 if ($htmlname !=
"none") {
8120 $out .=
'<form method="post" action="' . $page .
'">';
8121 $out .=
'<input type="hidden" name="action" value="set_thirdparty">';
8122 $out .=
'<input type="hidden" name="token" value="' .
newToken() .
'">';
8123 $out .= $this->select_company($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events, $limit,
'minwidth100',
'',
'', 1, array(),
false, $excludeids);
8124 $out .=
'<input type="submit" class="button smallpaddingimp valignmiddle" value="' . $langs->trans(
"Modify") .
'">';
8128 require_once DOL_DOCUMENT_ROOT .
'/societe/class/societe.class.php';
8129 $soc =
new Societe($this->db);
8130 $soc->fetch((
int) $selected);
8131 $out .= $soc->getNomUrl(0,
'');
8133 $out .=
'<span class="opacitymedium">' . $textifnothirdparty .
'</span>';
8159 print $this->selectCurrency($selected, $htmlname);
8171 public function selectCurrency($selected =
'', $htmlname =
'currency_id', $mode = 0, $useempty =
'')
8173 global $langs, $user;
8175 $langs->loadCacheCurrencies(
'');
8179 if ($selected ==
'euro' || $selected ==
'euros') {
8183 $out .=
'<select class="flat maxwidth200onsmartphone minwidth300" name="' . $htmlname .
'" id="' . $htmlname .
'">';
8185 $out .=
'<option value="-1" selected></option>';
8187 foreach ($langs->cache_currencies as $code_iso => $currency) {
8188 $labeltoshow = $currency[
'label'];
8190 $labeltoshow .=
' <span class="opacitymedium">(' . $code_iso .
')</span>';
8191 } elseif ($mode == 2) {
8192 $labeltoshow .=
' <span class="opacitymedium">(' . $code_iso.
' - '.$langs->getCurrencySymbol($code_iso) .
')</span>';
8194 $labeltoshow .=
' <span class="opacitymedium">(' . $langs->getCurrencySymbol($code_iso) .
')</span>';
8197 if ($selected && $selected == $code_iso) {
8198 $out .=
'<option value="' . $code_iso .
'" selected data-html="' .
dol_escape_htmltag($labeltoshow) .
'">';
8200 $out .=
'<option value="' . $code_iso .
'" data-html="' .
dol_escape_htmltag($labeltoshow) .
'">';
8203 $out .=
'</option>';
8205 $out .=
'</select>';
8207 $out .=
info_admin($langs->trans(
"YouCanChangeValuesForThisListFromDictionarySetup"), 1);
8211 include_once DOL_DOCUMENT_ROOT .
'/core/lib/ajax.lib.php';
8229 public function selectMultiCurrency($selected =
'', $htmlname =
'multicurrency_code', $useempty = 0, $filter =
'', $excludeConfCurrency =
false, $morecss =
'maxwidth200 widthcentpercentminusx')
8231 global
$conf, $langs;
8233 $langs->loadCacheCurrencies(
'');
8235 $TCurrency = array();
8237 $sql =
"SELECT code FROM " . $this->db->prefix() .
"multicurrency";
8238 $sql .=
" WHERE entity IN ('" .
getEntity(
'multicurrency') .
"')";
8242 $resql = $this->db->query($sql);
8244 while ($obj = $this->db->fetch_object($resql)) {
8245 $TCurrency[$obj->code] = $obj->code;
8250 $out .=
'<select class="flat' . ($morecss ?
' ' . $morecss :
'') .
'" name="' . $htmlname .
'" id="' . $htmlname .
'">';
8252 $out .=
'<option value=""> </option>';
8255 if (!in_array(
$conf->currency, $TCurrency) && !$excludeConfCurrency) {
8256 $TCurrency[
$conf->currency] =
$conf->currency;
8258 if (count($TCurrency) > 0) {
8259 foreach ($langs->cache_currencies as $code_iso => $currency) {
8260 if (isset($TCurrency[$code_iso])) {
8261 if (!empty($selected) && $selected == $code_iso) {
8262 $out .=
'<option value="' . $code_iso .
'" selected="selected">';
8264 $out .=
'<option value="' . $code_iso .
'">';
8267 $out .= $currency[
'label'];
8268 $out .=
' (' . $langs->getCurrencySymbol($code_iso) .
')';
8269 $out .=
'</option>';
8274 $out .=
'</select>';
8277 include_once DOL_DOCUMENT_ROOT .
'/core/lib/ajax.lib.php';
8294 global $langs, $user, $hookmanager;
8296 $num = count($this->cache_vatrates);
8305 $sql =
"SELECT t.rowid, t.entity, t.fk_pays, t.type_vat, t.code, t.taux, t.localtax1, t.localtax1_type, t.localtax2, t.localtax2_type, t.recuperableonly, t.einvoice_vatex";
8306 $sql .=
" FROM ".$this->db->prefix().
"c_tva as t, ".$this->db->prefix().
"c_country as c";
8307 $sql .=
" WHERE t.fk_pays = c.rowid";
8308 $sql .=
" AND t.active > 0";
8309 $sql .=
" AND t.entity IN (".getEntity(
'c_tva').
")";
8310 $sql .=
" AND c.code IN (" . $this->db->sanitize($country_code, 1) .
")";
8311 $sql .=
" ORDER BY t.code ASC, t.taux ASC, t.recuperableonly ASC";
8313 $resql = $this->db->query($sql);
8315 $num = $this->db->num_rows($resql);
8317 for ($i = 0; $i < $num; $i++) {
8318 $obj = $this->db->fetch_object($resql);
8320 $tmparray = array();
8321 $tmparray[
'rowid'] = (int) $obj->rowid;
8322 $tmparray[
'entity'] = (int) $obj->entity;
8323 $tmparray[
'fk_pays'] = (int) $obj->fk_pays;
8324 $tmparray[
'type_vat'] = ($obj->type_vat <= 0 ? 0 : $obj->type_vat);
8325 $tmparray[
'code'] = $obj->code;
8326 $tmparray[
'txtva'] = $obj->taux;
8327 $tmparray[
'nprtva'] = $obj->recuperableonly;
8328 $tmparray[
'localtax1'] = $obj->localtax1;
8329 $tmparray[
'localtax1_type'] = $obj->localtax1_type;
8330 $tmparray[
'localtax2'] = $obj->localtax2;
8331 $tmparray[
'localtax2_type'] = $obj->localtax1_type;
8332 $tmparray[
'einvoice_vatex'] = $obj->einvoice_vatex;
8334 $tmparray[
'label'] = $obj->taux .
'%' . ($obj->code ?
' (' . $obj->code .
')' :
'');
8335 $tmparray[
'labelallrates'] = $obj->taux .
'/' . ($obj->localtax1 ? $obj->localtax1 :
'0') .
'/' . ($obj->localtax2 ? $obj->localtax2 :
'0') . ($obj->code ?
' (' . $obj->code .
')' :
'');
8336 $positiverates =
'';
8338 $positiverates .= ($positiverates ?
'/' :
'') . $obj->taux;
8340 if ($obj->localtax1) {
8341 $positiverates .= ($positiverates ?
'/' :
'') . $obj->localtax1;
8343 if ($obj->localtax2) {
8344 $positiverates .= ($positiverates ?
'/' :
'') . $obj->localtax2;
8346 if (empty($positiverates)) {
8347 $positiverates =
'0';
8349 $tmparray[
'labelpositiverates'] = $positiverates . ($obj->code ?
' (' . $obj->code .
')' :
'');
8351 $this->cache_vatrates[$obj->rowid] = $tmparray;
8354 $parameters = array(
'dictionary' =>
'vatrate',
'country_code' => $country_code);
8355 $reshook = $hookmanager->executeHooks(
'loadDictionaryCache', $parameters, $this);
8356 if (empty($reshook)) {
8357 if (is_array($hookmanager->resArray) && count($hookmanager->resArray)) {
8358 $this->cache_vatrates = array_merge($this->cache_vatrates, $hookmanager->resArray);
8361 $this->cache_vatrates = $hookmanager->resArray;
8364 return count($this->cache_vatrates);
8366 $this->error =
'<span class="error">';
8367 $this->error .= $langs->trans(
"ErrorNoVATRateDefinedForSellerCountry", $country_code);
8369 if (!empty($user) && $user->admin && preg_match(
'/\'(..)\'/', $country_code, $reg)) {
8370 $langs->load(
"errors");
8371 $new_country_code = $reg[1];
8372 $country_id =
dol_getIdFromCode($this->db, $new_country_code,
'c_country',
'code',
'rowid');
8373 $this->error .=
'<br>'.$langs->trans(
"ErrorFixThisHere", DOL_URL_ROOT.
'/admin/dict.php?id=10'.($country_id > 0 ?
'&countryidforinsert='.$country_id :
''));
8375 $this->error .=
'</span>';
8379 $this->error =
'<span class="error">' . $this->db->error() .
'</span>';
8408 public function load_tva($htmlname =
'tauxtva', $selectedrate =
'', $societe_vendeuse =
null, $societe_acheteuse =
null, $idprod = 0, $info_bits = 0, $type =
'', $options_only =
false, $mode = 0, $type_vat = 0)
8411 global $langs,
$mysoc, $hookmanager;
8413 $langs->load(
'errors');
8417 $hookmanager->initHooks(array(
'commonobject'));
8418 $info_bits == 1 ? $is_npr = 1 : $is_npr = 0;
8419 $parameters = array(
8420 'htmlname' => $htmlname,
8421 'selectedrate' => $selectedrate,
8422 'seller' => $societe_vendeuse,
8423 'buyer' => $societe_acheteuse,
8424 'idprod' => $idprod,
8425 'is_npr' => $is_npr,
8427 'options_only' => $options_only,
8429 'type_vat' => $type_vat
8431 $reshook = $hookmanager->executeHooks(
'load_tva', $parameters);
8433 return $hookmanager->resPrint;
8434 } elseif ($reshook === 0) {
8435 $return .= $hookmanager->resPrint;
8439 $defaultnpr = ($info_bits & 0x01);
8440 $defaultnpr = (preg_match(
'/\*/', $selectedrate) ? 1 : $defaultnpr);
8441 $defaulttx = str_replace(
'*',
'', $selectedrate);
8444 if (preg_match(
'/\((.*)\)/', $defaulttx, $reg)) {
8445 $defaultcode = $reg[1];
8446 $defaulttx = preg_replace(
'/\s*\(.*\)/',
'', $defaulttx);
8451 if (is_object($societe_vendeuse) && !$societe_vendeuse->country_code) {
8452 if ($societe_vendeuse->id ==
$mysoc->id) {
8453 $return .=
'<span class="error">' . $langs->trans(
"ErrorYourCountryIsNotDefined") .
'</span>';
8455 $return .=
'<span class="error">' . $langs->trans(
"ErrorSupplierCountryIsNotDefined") .
'</span>';
8472 $sellercountrycode = is_object($societe_vendeuse) ? $societe_vendeuse->country_code :
$mysoc->country_code;
8473 $sellercountryid = is_object($societe_vendeuse) ? $societe_vendeuse->country_id :
$mysoc->country_id;
8474 if ((
int) $sellercountryid > 0 && strlen((
string) $sellercountrycode) != 2) {
8475 $tmpcountrycode =
dol_getIdFromCode($this->db, (
string) $sellercountryid,
'c_country',
'rowid',
'code');
8476 if (!empty($tmpcountrycode) && !is_numeric($tmpcountrycode)) {
8477 $sellercountrycode = $tmpcountrycode;
8480 $code_country =
"'" . $sellercountrycode .
"'";
8483 require_once DOL_DOCUMENT_ROOT .
'/core/lib/company.lib.php';
8487 if (is_object($societe_vendeuse) && is_object($societe_acheteuse) &&
isInEEC($societe_vendeuse) &&
isInEEC($societe_acheteuse) && !$societe_acheteuse->isACompany()) {
8489 if (is_numeric($type)) {
8491 switch ($selectVatComboMode) {
8493 $code_country .=
",'" . $societe_acheteuse->country_code .
"'";
8496 $code_country =
"'" . $societe_acheteuse->country_code .
"'";
8500 } elseif (!$idprod) {
8501 switch ($selectVatComboMode) {
8503 $code_country .=
",'" . $societe_acheteuse->country_code .
"'";
8506 $code_country =
"'" . $societe_acheteuse->country_code .
"'";
8510 $prodstatic =
new Product($this->db);
8511 $prodstatic->fetch($idprod);
8513 $code_country .=
",'" . $societe_acheteuse->country_code .
"'";
8520 $this->load_cache_vatrates($code_country);
8523 $arrayofvatrates = array();
8524 foreach ($this->cache_vatrates as $cachevalue) {
8525 if (empty($cachevalue[
'type_vat']) || $cachevalue[
'type_vat'] == $type_vat) {
8526 $arrayofvatrates[] = $cachevalue;
8530 $num = count($arrayofvatrates);
8533 if ($defaulttx < 0 ||
dol_strlen($defaulttx) == 0) {
8535 $tmpthirdparty =
new Societe($this->db);
8536 $tmpthirdparty->country_code =
$mysoc->country_code;
8538 $defaulttx =
get_default_tva(is_object($societe_vendeuse) ? $societe_vendeuse : $tmpthirdparty, (is_object($societe_acheteuse) ? $societe_acheteuse : $tmpthirdparty), $idprod);
8539 $defaultnpr =
get_default_npr(is_object($societe_vendeuse) ? $societe_vendeuse : $tmpthirdparty, (is_object($societe_acheteuse) ? $societe_acheteuse : $tmpthirdparty), $idprod);
8541 if (preg_match(
'/\((.*)\)/', $defaulttx, $reg)) {
8542 $defaultcode = $reg[1];
8543 $defaulttx = preg_replace(
'/\s*\(.*\)/',
'', $defaulttx);
8545 if (empty($defaulttx)) {
8552 if ($defaulttx < 0 ||
dol_strlen($defaulttx) == 0) {
8555 $defaulttx = $arrayofvatrates[$num - 1][
'txtva'];
8562 if (preg_match(
'/\((.*)\)/', $defaulttx, $reg)) {
8563 $defaultcode = $reg[1];
8564 $defaulttx = preg_replace(
'/\s*\(.*\)/',
'', $defaulttx);
8572 if (is_object($societe_vendeuse) && $societe_vendeuse->id ==
$mysoc->id && empty($societe_vendeuse->tva_assuj)) {
8582 if (!$options_only) {
8583 $return .=
'<select class="flat valignmiddle minwidth75imp maxwidth100 right" id="' . $htmlname .
'" name="' . $htmlname .
'"' . ($disabled ?
' disabled' :
'') . $title .
'>';
8586 $selectedfound =
false;
8587 foreach ($arrayofvatrates as $rate) {
8589 if ($disabled && $rate[
'txtva'] != 0) {
8594 $key = $rate[
'txtva'];
8595 $key .= $rate[
'nprtva'] ?
'*' :
'';
8596 if ($mode > 0 && $rate[
'code']) {
8597 $key .=
' (' . $rate[
'code'] .
')';
8600 $key = $rate[
'rowid'];
8603 $return .=
'<option value="' . $key .
'" data-vatid="'.$rate[
'rowid'].
'"';
8604 if (!$selectedfound) {
8606 if ($defaultcode == $rate[
'code']) {
8607 $return .=
' selected';
8608 $selectedfound =
true;
8610 } elseif ($rate[
'txtva'] == $defaulttx && $rate[
'nprtva'] == $defaultnpr) {
8611 $return .=
' selected';
8612 $selectedfound =
true;
8620 $return .= $rate[
'labelpositiverates'];
8623 $return .=
vatrate($rate[
'label']);
8627 $return .= (empty($rate[
'code']) && $rate[
'nprtva']) ?
' *' :
'';
8629 $return .=
'</option>';
8632 if (!$options_only) {
8633 $return .=
'</select>';
8637 $return .= $this->error;
8671 public function select_date($set_time =
'', $prefix =
're', $h = 0, $m = 0, $empty = 0, $form_name =
"", $d = 1, $addnowlink = 0, $nooutput = 0, $disabled = 0, $fullday = 0, $addplusone =
'', $adddateof =
'')
8674 dol_syslog(__METHOD__ .
': using select_date is deprecated. Use selectDate instead.', LOG_WARNING);
8675 $retstring = $this->selectDate($set_time, $prefix, $h, $m, $empty, $form_name, $d, $addnowlink, $disabled, $fullday, $addplusone, $adddateof);
8676 if (!empty($nooutput)) {
8699 public function selectDateToDate($set_time =
'', $set_time_end =
'', $prefix =
're', $empty = 0, $forcenewline = 0)
8703 $ret = $this->selectDate($set_time, $prefix .
'_start', 0, 0, $empty,
'', 1, 0, 0,
'',
'',
'',
'', 1,
'', $langs->trans(
"from"),
'tzuserrel');
8704 if ($forcenewline) {
8707 $ret .= $this->selectDate($set_time_end, $prefix .
'_end', 0, 0, $empty,
'', 1, 0, 0,
'',
'',
'',
'', 1,
'', $langs->trans(
"to"),
'tzuserrel');
8739 public function selectDate($set_time =
'', $prefix =
're', $h = 0, $m = 0, $empty = 0, $form_name =
"", $d = 1, $addnowlink = 0, $disabled = 0, $fullday =
'', $addplusone =
'', $adddateof =
'', $openinghours =
'', $stepminutes = 1, $labeladddateof =
'', $placeholder =
'', $gm =
'auto', $calendarpicto =
'')
8741 global
$conf, $langs;
8743 if ($gm ===
'auto') {
8744 $gm = (empty(
$conf) ?
'tzserver' :
$conf->tzuserinputkey);
8749 if ($prefix ==
'') {
8760 if ($stepminutes <= 0 || $stepminutes > 30) {
8771 $orig_set_time = $set_time;
8773 if ($set_time ===
'' && $emptydate == 0) {
8774 include_once DOL_DOCUMENT_ROOT .
'/core/lib/date.lib.php';
8775 if ($gm ==
'tzuser' || $gm ==
'tzuserrel') {
8787 if (!empty($set_time) && preg_match(
'/^([0-9]+)\-([0-9]+)\-([0-9]+)\s?([0-9]+)?:?([0-9]+)?/', (
string) $set_time, $reg)) {
8789 $syear = (!empty($reg[1]) ? $reg[1] :
'');
8790 $smonth = (!empty($reg[2]) ? $reg[2] :
'');
8791 $sday = (!empty($reg[3]) ? $reg[3] :
'');
8792 $shour = (!empty($reg[4]) ? $reg[4] :
'');
8793 $smin = (!empty($reg[5]) ? $reg[5] :
'');
8794 } elseif (strval($set_time) !=
'' && $set_time != -1) {
8799 if ($orig_set_time !=
'') {
8813 if ($h == 3 || $h == 4) {
8824 $usecalendar =
'combo';
8830 $usecalendar =
'html';
8835 if ($usecalendar !=
'combo') {
8837 $reduceformat = (!empty(
$conf->dol_optimize_smallscreen) ? 1 : 0);
8838 if ($reduceformat) {
8839 $format = str_replace(
'%Y',
'%y', $langs->transnoentitiesnoconv(
"FormatDateShortInput"));
8840 $formatjslong = $langs->transnoentitiesnoconv(
"FormatDateShortJavaInput");
8841 $formatjs = str_replace(
'yyyy',
'yy', $langs->transnoentitiesnoconv(
"FormatDateShortJavaInput"));
8842 $formatjquery = str_replace(
'yyyy',
'yy', $langs->trans(
"FormatDateShortJQueryInput"));
8844 $format = $langs->transnoentitiesnoconv(
"FormatDateShortInput");
8845 $formatjslong = $langs->transnoentitiesnoconv(
"FormatDateShortJavaInput");
8846 $formatjs = $langs->transnoentitiesnoconv(
"FormatDateShortJavaInput");
8847 $formatjquery = $langs->trans(
"FormatDateShortJQueryInput");
8851 $formatted_date =
'';
8852 if (strval($set_time) !=
'' && $set_time != -1) {
8857 if ($usecalendar ==
"eldy") {
8883 } elseif ($usecalendar ==
'jquery' || $usecalendar ==
'html') {
8884 if (!$disabled && $usecalendar !=
'html') {
8886 $minYear =
getDolGlobalInt(
'MIN_YEAR_SELECT_DATE', (idate(
'Y') - 100));
8887 $maxYear =
getDolGlobalInt(
'MAX_YEAR_SELECT_DATE', (idate(
'Y') + 100));
8889 $retstring .=
'<!-- datepicker usecalendar='.$usecalendar.
' --><script nonce="' .
getNonce() .
'" type="text/javascript">';
8890 $retstring .=
"$(function(){ $('#" . $prefix .
"').datepicker({
8893 todayHighlight: true,
8894 yearRange: '" . $minYear .
":" . $maxYear .
"',";
8895 if (!empty(
$conf->dol_use_jmobile)) {
8897 beforeShow: function (input, datePicker) {
8898 input.disabled = true;
8900 onClose: function (dateText, datePicker) {
8901 this.disabled = false;
8907 $buttonImage = $calendarpicto ?: DOL_URL_ROOT .
"/theme/" .
dol_escape_js(
$conf->theme) .
"/img/object_calendarday.png";
8909 showOn: 'button', /* both has problem with autocompletion */
8910 buttonImage: '" . $buttonImage .
"',
8911 buttonImageOnly: true";
8915 $retstring .=
"</script>";
8919 $retstring .=
'<div class="nowraponall inline-block divfordateinput">';
8920 $retstring .=
'<input id="'.$prefix.
'" name="'.$prefix.
'" type="'.($usecalendar ==
'html' ?
"date" :
"text").
'" class="maxwidthdate'.(
getDolUserString(
'MAIN_OPTIMIZEFORTEXTBROWSER') ?
' textbrowser' :
'').
' center" maxlength="11" value="'.$formatted_date.
'"';
8921 $retstring .= ($disabled ?
' disabled' :
'');
8922 $retstring .= ($placeholder ?
' placeholder="' .
dol_escape_htmltag($placeholder) .
'"' :
'');
8923 $retstring .=
' onChange="dpChangeDay(\'' .
dol_escape_js($prefix) .
'\',\
'' .
dol_escape_js($usecalendar ==
'html' ?
'yyyy-mm-dd' : $formatjslong) .
'\');
"'; // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript
8924 $retstring .= ' autocomplete="off
">';
8928 $retstringbutton = '<button id="' . $prefix . 'Button
" type="button" class="dpInvisibleButtons
">' . img_object($langs->trans("Disabled
"), 'calendarday', 'class="datecallink ui-datepicker-notrigger
"') . '</button>';
8929 $retstring .= $retstringbutton;
8932 $retstring .= '</div>';
8933 $retstring .= '<input type="hidden
" id="' . $prefix . 'day
" name="' . $prefix . 'day
" value="' . $sday . '">' . "\n
";
8934 $retstring .= '<input type="hidden
" id="' . $prefix . 'month
" name="' . $prefix . 'month
" value="' . $smonth . '">' . "\n
";
8935 $retstring .= '<input type="hidden
" id="' . $prefix . 'year
" name="' . $prefix . 'year
" value="' . $syear . '">' . "\n
";
8937 $retstring .= "Bad value of MAIN_POPUP_CALENDAR
";
8940 // Show date with combo selects
8942 $retstring .= '<select' . ($disabled ? ' disabled' : '') . ' class="flat valignmiddle maxwidth50imp
" id="' . $prefix . 'day
" name="' . $prefix . 'day
">';
8944 if ($emptydate || $set_time == -1) {
8945 $retstring .= '<option value="0
" selected> </option>';
8948 for ($day = 1; $day <= 31; $day++) {
8949 $retstring .= '<option value="' . $day . '"' . ($day == $sday ? ' selected' : '') . '>' . $day . '</option>';
8952 $retstring .= "</select>
";
8954 $retstring .= '<select' . ($disabled ? ' disabled' : '') . ' class="flat valignmiddle maxwidth75imp
" id="' . $prefix . 'month
" name="' . $prefix . 'month
">';
8955 if ($emptydate || $set_time == -1) {
8956 $retstring .= '<option value="0
" selected> </option>';
8960 for ($month = 1; $month <= 12; $month++) {
8961 $retstring .= '<option value="' . $month . '"' . ($month == $smonth ? ' selected' : '') . '>';
8962 $retstring .= dol_print_date(mktime(12, 0, 0, $month, 1, 2000), "%b
");
8963 $retstring .= "</option>
";
8965 $retstring .= "</select>
";
8968 if ($emptydate || $set_time == -1) {
8969 $retstring .= '<input' . ($disabled ? ' disabled' : '') . ' placeholder="' . dol_escape_htmltag($langs->trans("Year")) . '" class="flat maxwidth50imp valignmiddle
" type="number
" min="0
" max="3000
" maxlength="4
" id="' . $prefix . 'year
" name="' . $prefix . 'year
" value="' . $syear . '">';
8971 $retstring .= '<select' . ($disabled ? ' disabled' : '') . ' class="flat valignmiddle maxwidth75imp
" id="' . $prefix . 'year
" name="' . $prefix . 'year
">';
8973 $syear = (int) $syear;
8974 for ($year = $syear - 10; $year < (int) $syear + 10; $year++) {
8975 $retstring .= '<option value="' . $year . '"' . ($year == $syear ? ' selected' : '') . '>' . $year . '</option>';
8977 $retstring .= "</select>\n
";
8983 $retstring .= (($h == 2 || $h == 4) ? '<br>' : ' ');
8984 $retstring .= '<span class="nowraponall
">';
8990 if ($openinghours != '') {
8991 $openinghours = explode(',', $openinghours);
8992 $hourstart = $openinghours[0];
8993 $hourend = $openinghours[1];
8994 if ($hourend < $hourstart) {
8995 $hourend = $hourstart;
9000 $retstring .= '<select' . ($disabled ? ' disabled' : '') . ' class="flat valignmiddle maxwidth75
'; // Note maxwidth50 generates truncated number on some desktops even with same version of chrome that works on others
9001 $retstring .= ($fullday ? $fullday . 'hour
' : '') . '" id="' . $prefix . 'hour
" name="' . $prefix . 'hour
">';
9003 $retstring .= '<option value="-1
"> </option>';
9005 for ($hour = $hourstart; $hour < $hourend; $hour++) {
9006 if (strlen($hour) < 2) {
9007 $hour = "0
" . $hour;
9009 $retstring .= '<option value="' . $hour . '"' . (($hour == $shour) ? ' selected' : '') . '>' . $hour;
9010 $retstring .= '</option>';
9012 $retstring .= '</select>';
9015 $retstring .= '<input type="hidden
" id="' . $prefix . 'hour
" name="' . $prefix . 'hour
" value="' . $shour . '">' . "\n
";
9024 $retstring .= '<select ' . ($disabled ? ' disabled' : '') . ' class="flat valignmiddle maxwidth75
'; // Note maxwidth50 generates truncated number on some desktops even with same version of chrome that works on others
9025 $retstring .= ($fullday ? $fullday . 'min
' : '') . '" id="' . $prefix . 'min
" name="' . $prefix . 'min
">';
9027 $retstring .= '<option value="-1
"> </option>';
9029 for ($min = 0; $min < 60; $min += $stepminutes) {
9030 $min_str = sprintf("%02d
", $min);
9031 $retstring .= '<option value="' . $min_str . '"' . (($min_str == $smin) ? ' selected' : '') . '>' . $min_str . '</option>';
9033 $retstring .= '</select>';
9035 $retstring .= '<input type="hidden
" id="' . $prefix . 'min
" name="' . $prefix . 'min
" value="' . $smin . '">' . "\n
";
9038 $retstring .= '<input type="hidden
" name="' . $prefix . 'sec
" value="' . $ssec . '">';
9042 $retstring .= '</span>';
9046 if (!empty($conf->use_javascript_ajax) && $addnowlink && !$disabled) {
9047 // Script which will be inserted in the onClick of the "Now
" link
9048 $reset_scripts = "";
9049 if ($addnowlink == 2) { // local computer time
9050 // pad add leading 0 on numbers
9051 $reset_scripts .= "Number.prototype.pad =
function(size) {
9052 var s = String(
this);
9053 while (s.length < (size || 2)) {s =
'0' + s;}
9056 var d =
new Date();
";
9059 // Generate the date part, depending on the use or not of the javascript calendar
9060 if ($addnowlink == 1) { // server time expressed in user time setup
9061 $reset_scripts .= 'jQuery(\'#' . $prefix . '\').val(\'' . dol_print_date($nowgmt, 'day', 'tzuserrel') . '\');';
9062 $reset_scripts .= 'jQuery(\'#' . $prefix . 'day\').val(\'' . dol_print_date($nowgmt, '%d', 'tzuserrel') . '\');';
9063 $reset_scripts .= 'jQuery(\'#' . $prefix . 'month\').val(\'' . dol_print_date($nowgmt, '%m', 'tzuserrel') . '\');';
9064 $reset_scripts .= 'jQuery(\'#' . $prefix . 'year\').val(\'' . dol_print_date($nowgmt, '%Y', 'tzuserrel') . '\');';
9065 } elseif ($addnowlink == 2) {
9066 /* Disabled because the output does not use the string format defined by FormatDateShort key to forge the value into #prefix.
9067 * This break application for foreign languages.
9068 $reset_scripts .= 'jQuery(\'#'.$prefix.'\').val(d.toLocaleDateString(\''.str_replace('_', '-', $langs->defaultlang).'\'));';
9069 $reset_scripts .= 'jQuery(\'#'.$prefix.'day\').val(d.getDate().pad());';
9070 $reset_scripts .= 'jQuery(\'#'.$prefix.'month\').val(parseInt(d.getMonth().pad()) + 1);';
9071 $reset_scripts .= 'jQuery(\'#'.$prefix.'year\').val(d.getFullYear());';
9073 $reset_scripts .= 'jQuery(\'#' . $prefix . '\').val(\'' . dol_print_date($nowgmt, 'day', 'tzuserrel') . '\');';
9074 $reset_scripts .= 'jQuery(\'#' . $prefix . 'day\').val(\'' . dol_print_date($nowgmt, '%d', 'tzuserrel') . '\');';
9075 $reset_scripts .= 'jQuery(\'#' . $prefix . 'month\').val(\'' . dol_print_date($nowgmt, '%m', 'tzuserrel') . '\');';
9076 $reset_scripts .= 'jQuery(\'#' . $prefix . 'year\').val(\'' . dol_print_date($nowgmt, '%Y', 'tzuserrel') . '\');';
9078 /*if ($usecalendar == "eldy
")
9080 $base=DOL_URL_ROOT.'/core/';
9081 $reset_scripts .= 'resetDP(\''.$base.'\',\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput
").'\',\''.$langs->defaultlang.'\');';
9085 $reset_scripts .= 'this.form.elements[\''.$prefix.'day\'].value=formatDate(new Date(), \'d\'); ';
9086 $reset_scripts .= 'this.form.elements[\''.$prefix.'month\'].value=formatDate(new Date(), \'M\'); ';
9087 $reset_scripts .= 'this.form.elements[\''.$prefix.'year\'].value=formatDate(new Date(), \'yyyy\'); ';
9089 // Update the hour part
9092 $reset_scripts .= " if (jQuery(
'#fullday:checked').val() ==
null) {
";
9094 //$reset_scripts .= 'this.form.elements[\''.$prefix.'hour\'].value=formatDate(new Date(), \'HH\'); ';
9095 if ($addnowlink == 1) {
9096 $reset_scripts .= 'jQuery(\'#' . $prefix . 'hour\').val(\'' . dol_print_date($nowgmt, '%H', 'tzuserrel') . '\');';
9097 $reset_scripts .= 'jQuery(\'#' . $prefix . 'hour\').change();';
9098 } elseif ($addnowlink == 2) {
9099 $reset_scripts .= 'jQuery(\'#' . $prefix . 'hour\').val(d.getHours().pad());';
9100 $reset_scripts .= 'jQuery(\'#' . $prefix . 'hour\').change();';
9104 $reset_scripts .= ' } ';
9107 // Update the minute part
9110 $reset_scripts .= " if (jQuery(
'#fullday:checked').val() ==
null) {
";
9112 //$reset_scripts .= 'this.form.elements[\''.$prefix.'min\'].value=formatDate(new Date(), \'mm\'); ';
9113 if ($addnowlink == 1) {
9114 $reset_scripts .= 'jQuery(\'#' . $prefix . 'min\').val(\'' . dol_print_date($nowgmt, '%M', 'tzuserrel') . '\');';
9115 $reset_scripts .= 'jQuery(\'#' . $prefix . 'min\').change();';
9116 } elseif ($addnowlink == 2) {
9117 $reset_scripts .= 'jQuery(\'#' . $prefix . 'min\').val(d.getMinutes().pad());';
9118 $reset_scripts .= 'jQuery(\'#' . $prefix . 'min\').change();';
9121 $reset_scripts .= ' } ';
9124 // If reset_scripts is not empty, print the link with the reset_scripts in the onClick
9125 if ($reset_scripts && !getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
9126 $retstring .= ' <button class="dpInvisibleButtons datenowlink
" id="' . $prefix . 'ButtonNow
" type="button" name="_useless
" value="now
" onClick="' . $reset_scripts . '">';
9127 $retstring .= $langs->trans("Now
");
9128 $retstring .= '</button> ';
9132 // Add a "Plus one hour
" link
9133 if ($conf->use_javascript_ajax && $addplusone && !$disabled) {
9134 // Script which will be inserted in the onClick of the "Add plusone
" link
9135 $reset_scripts = "";
9137 // Generate the date part, depending on the use or not of the javascript calendar
9138 $reset_scripts .= 'jQuery(\'#' . $prefix . '\').val(\'' . dol_print_date($nowgmt, 'dayinputnoreduce', 'tzuserrel') . '\');';
9139 $reset_scripts .= 'jQuery(\'#' . $prefix . 'day\').val(\'' . dol_print_date($nowgmt, '%d', 'tzuserrel') . '\');';
9140 $reset_scripts .= 'jQuery(\'#' . $prefix . 'month\').val(\'' . dol_print_date($nowgmt, '%m', 'tzuserrel') . '\');';
9141 $reset_scripts .= 'jQuery(\'#' . $prefix . 'year\').val(\'' . dol_print_date($nowgmt, '%Y', 'tzuserrel') . '\');';
9142 // Update the hour part
9145 $reset_scripts .= " if (jQuery(
'#fullday:checked').val() ==
null) {
";
9147 $reset_scripts .= 'jQuery(\'#' . $prefix . 'hour\').val(\'' . dol_print_date($nowgmt, '%H', 'tzuserrel') . '\');';
9149 $reset_scripts .= ' } ';
9152 // Update the minute part
9155 $reset_scripts .= " if (jQuery(
'#fullday:checked').val() ==
null) {
";
9157 $reset_scripts .= 'jQuery(\'#' . $prefix . 'min\').val(\'' . dol_print_date($nowgmt, '%M', 'tzuserrel') . '\');';
9159 $reset_scripts .= ' } ';
9162 // If reset_scripts is not empty, print the link with the reset_scripts in the onClick
9163 if ($reset_scripts && empty($conf->dol_optimize_smallscreen)) {
9164 $retstring .= ' <button class="dpInvisibleButtons datenowlink
" id="' . $prefix . 'ButtonPlusOne
" type="button" name="_useless2
" value="plusone
" onClick="' . $reset_scripts . '">';
9165 $retstring .= $langs->trans("DateStartPlusOne
");
9166 $retstring .= '</button> ';
9170 // Add a link to set data
9171 if ($conf->use_javascript_ajax && !empty($adddateof) && !$disabled) {
9172 if (!is_array($adddateof)) {
9173 $arrayofdateof = array(array('adddateof' => $adddateof, 'labeladddateof' => $labeladddateof));
9175 $arrayofdateof = $adddateof;
9177 foreach ($arrayofdateof as $valuedateof) {
9178 $tmpadddateof = empty($valuedateof['adddateof']) ? 0 : $valuedateof['adddateof'];
9179 $tmplabeladddateof = empty($valuedateof['labeladddateof']) ? '' : $valuedateof['labeladddateof'];
9180 $tmparray = dol_getdate($tmpadddateof);
9181 if (empty($tmplabeladddateof)) {
9182 $tmplabeladddateof = $langs->trans("DateInvoice
");
9184 $reset_scripts = 'console.log(\'Click on now link\'); ';
9185 $reset_scripts .= 'jQuery(\'#'.$prefix.'\').val(\''.dol_print_date($tmpadddateof, 'dayinputnoreduce').'\');';
9186 $reset_scripts .= 'jQuery(\'#'.$prefix.'day\').val(\''.$tmparray['mday'].'\');';
9187 $reset_scripts .= 'jQuery(\'#'.$prefix.'month\').val(\''.$tmparray['mon'].'\');';
9188 $reset_scripts .= 'jQuery(\'#'.$prefix.'year\').val(\''.$tmparray['year'].'\');';
9189 $retstring .= ' - <button class="dpInvisibleButtons datenowlink
" id="dateofinvoice
" type="button" name="_dateofinvoice
" value="now
" onclick="'.$reset_scripts.'">'.$tmplabeladddateof.'</button>';
9205 public function selectTypeDuration($prefix, $selected = 'i', $excludetypes = array(), $morecss = 'minwidth75 maxwidth100')
9209 $TDurationTypes = $this->getDurationTypes($langs);
9211 // Removed undesired duration types
9212 foreach ($excludetypes as $value) {
9213 unset($TDurationTypes[$value]);
9216 $retstring = '<select class="flat
'.($morecss ? ' '.$morecss : '').'" id="select_
' . $prefix . 'type_duration
" name="' . $prefix . 'type_duration
">';
9217 foreach ($TDurationTypes as $key => $typeduration) {
9218 $retstring .= '<option value="' . $key . '"';
9219 if ($key == $selected) {
9220 $retstring .= " selected
";
9222 $retstring .= ">
" . $typeduration . "</option>
";
9224 $retstring .= "</select>
";
9226 $retstring .= ajax_combobox('select_' . $prefix . 'type_duration');
9231 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
9246 public function select_duration($prefix, $iSecond = '', $disabled = 0, $typehour = 'select', $minunderhours = 0, $nooutput = 0)
9251 $retstring = '<span class="nowraponall
">';
9257 if ($iSecond != '') {
9258 require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
9260 $hourSelected = convertSecondToTime($iSecond, 'allhour');
9261 $minSelected = convertSecondToTime($iSecond, 'min');
9264 if ($typehour == 'select') {
9265 $retstring .= '<select class="flat
" id="select_
' . $prefix . 'hour
" name="' . $prefix . 'hour
"' . ($disabled ? ' disabled' : '') . '>';
9266 for ($hour = 0; $hour < 25; $hour++) { // For a duration, we allow 24 hours
9267 $retstring .= '<option value="' . $hour . '"';
9268 if (is_numeric($hourSelected) && $hourSelected == $hour) {
9269 $retstring .= " selected
";
9271 $retstring .= ">
" . $hour . "</option>
";
9273 $retstring .= "</select>
";
9274 } elseif ($typehour == 'text' || $typehour == 'textselect') {
9275 $retstring .= '<input placeholder="' . $langs->trans('HourShort
') . '" type="number
" min="0
" name="' . $prefix . 'hour
"' . ($disabled ? ' disabled' : '') . ' class="flat maxwidth50 inputhour right
" value="' . (($hourSelected != '') ? ((int) $hourSelected) : '') . '">';
9277 return 'BadValueForParameterTypeHour';
9280 if ($typehour != 'text') {
9281 $retstring .= ' ' . $langs->trans('HourShort');
9283 $retstring .= '<span class="">:</span>';
9287 if ($minunderhours) {
9288 $retstring .= '<br>';
9290 if ($typehour != 'text') {
9291 $retstring .= '<span class="hideonsmartphone
"> </span>';
9295 if ($typehour == 'select' || $typehour == 'textselect') {
9296 $retstring .= '<select class="flat
" id="select_
' . $prefix . 'min
" name="' . $prefix . 'min
"' . ($disabled ? ' disabled' : '') . '>';
9297 $step = getDolGlobalInt('MAIN_DURATION_STEP');
9298 $duration_step = ($step > 0) ? $step : 5;
9299 for ($min = 0; $min <= 59; $min += $duration_step) {
9300 $retstring .= '<option value="' . $min . '"';
9301 if (is_numeric($minSelected) && $minSelected == $min) {
9302 $retstring .= ' selected';
9304 $retstring .= '>' . $min . '</option>';
9306 $retstring .= "</select>
";
9307 } elseif ($typehour == 'text') {
9308 $retstring .= '<input placeholder="' . $langs->trans('MinuteShort
') . '" type="number
" min="0
" name="' . $prefix . 'min
"' . ($disabled ? ' disabled' : '') . ' class="flat maxwidth50 inputminute right
" value="' . (($minSelected != '') ? ((int) $minSelected) : '') . '">';
9311 if ($typehour != 'text') {
9312 $retstring .= ' ' . $langs->trans('MinuteShort');
9315 $retstring .= "</span>
";
9317 if (!empty($nooutput)) {
9345 public function selectTickets($selected = '', $htmlname = 'ticketid', $filtertype = '', $limit = 0, $status = 1, $selected_input_value = '', $hidelabel = 0, $ajaxoptions = array(), $socid = 0, $showempty = '1', $forcecombo = 0, $morecss = '', $selected_combinations = null, $nooutput = 0)
9347 global $langs, $conf;
9352 if (is_null($ajaxoptions)) {
9353 $ajaxoptions = array();
9356 if (!empty($conf->use_javascript_ajax) && getDolGlobalString('TICKET_USE_SEARCH_TO_SELECT')) {
9359 if ($selected && empty($selected_input_value)) {
9360 require_once DOL_DOCUMENT_ROOT . '/ticket/class/ticket.class.php';
9361 $tickettmpselect = new Ticket($this->db);
9362 $tickettmpselect->fetch((int) $selected);
9363 $selected_input_value = $tickettmpselect->ref;
9364 unset($tickettmpselect);
9368 $out .= ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT . '/ticket/ajax/tickets.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 1, $ajaxoptions);
9370 if (empty($hidelabel)) {
9371 $out .= $langs->trans("RefOrLabel
") . ' : ';
9372 } elseif ($hidelabel > 1) {
9373 $placeholder = ' placeholder="' . $langs->trans("RefOrLabel") . '"';
9374 if ($hidelabel == 2) {
9375 $out .= img_picto($langs->trans("Search
"), 'search');
9378 $out .= '<input type="text
" class="minwidth100
" name="search_
' . $htmlname . '" id="search_
' . $htmlname . '" value="' . $selected_input_value . '"' . $placeholder . ' ' . (getDolGlobalString('PRODUCT_SEARCH_AUTOFOCUS') ? 'autofocus' : '') . ' />';
9379 if ($hidelabel == 3) {
9380 $out .= img_picto($langs->trans("Search
"), 'search');
9383 $out .= $this->selectTicketsList($selected, $htmlname, $filtertype, $limit, '', $status, 0, $showempty, $forcecombo, $morecss);
9386 if (empty($nooutput)) {
9411 public function selectTicketsList($selected = '', $htmlname = 'ticketid', $filtertype = '', $limit = 20, $filterkey = '', $status = 1, $outputmode = 0, $showempty = '1', $forcecombo = 0, $morecss = '')
9416 $outarray = array();
9418 $selectFields = " p.rowid, p.ref, p.message
";
9421 $sql .= $this->db->sanitize($selectFields, 0, 0, 1);
9422 $sql .= " FROM
" . $this->db->prefix() . "ticket as p
";
9423 $sql .= ' WHERE p.entity IN (' . getEntity('ticket') . ')';
9425 // Add criteria on ref/label
9426 if ($filterkey != '') {
9428 $prefix = getDolGlobalString('TICKET_DONOTSEARCH_ANYWHERE') ? '' : '%'; // Can use index if TICKET_DONOTSEARCH_ANYWHERE is on
9429 // For natural search
9430 $search_crit = explode(' ', $filterkey);
9432 if (count($search_crit) > 1) {
9435 foreach ($search_crit as $crit) {
9439 $sql .= "(p.ref LIKE
'" . $this->db->escape($prefix . $crit) . "%' OR p.subject LIKE
'" . $this->db->escape($prefix . $crit) . "%'";
9443 if (count($search_crit) > 1) {
9449 $sql .= $this->db->plimit($limit, 0);
9451 // Build output string
9452 dol_syslog(get_class($this) . "::selectTicketsList search tickets
", LOG_DEBUG);
9453 $result = $this->db->query($sql);
9455 require_once DOL_DOCUMENT_ROOT . '/ticket/class/ticket.class.php';
9456 require_once DOL_DOCUMENT_ROOT . '/core/lib/ticket.lib.php';
9458 $num = $this->db->num_rows($result);
9463 include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
9464 $out .= ajax_combobox($htmlname, $events, getDolGlobalInt('TICKET_USE_SEARCH_TO_SELECT'));
9467 $out .= '<select class="flat
' . ($morecss ? ' ' . $morecss : '') . '" name="' . $htmlname . '" id="' . $htmlname . '">';
9470 // Do not use textifempty = ' ' or ' ' here, or search on key will search on ' key'.
9471 //if (!empty($conf->use_javascript_ajax) || $forcecombo) $textifempty='';
9472 if (getDolGlobalString('TICKET_USE_SEARCH_TO_SELECT')) {
9473 if ($showempty && !is_numeric($showempty)) {
9474 $textifempty = $langs->trans($showempty);
9476 $textifempty .= $langs->trans("All
");
9479 if ($showempty && !is_numeric($showempty)) {
9480 $textifempty = $langs->trans($showempty);
9484 $out .= '<option value="0
" selected>' . $textifempty . '</option>';
9488 while ($num && $i < $num) {
9491 $objp = $this->db->fetch_object($result);
9493 $this->constructTicketListOption($objp, $opt, $optJson, $selected, $filterkey);
9494 '@phan-var-force array{key:string,value:mixed,type:int} $optJson';
9496 // "key
" value of json key array is used by jQuery automatically as selected value
9497 // "label
" value of json key array is used by jQuery automatically as text for combo box
9499 array_push($outarray, $optJson);
9504 $out .= '</select>';
9506 $this->db->free($result);
9508 if (empty($outputmode)) {
9513 dol_print_error($this->db);
9530 protected function constructTicketListOption(&$objp, &$opt, &$optJson, $selected, $filterkey = '')
9536 $outkey = $objp->rowid;
9537 $outref = $objp->ref;
9539 $opt = '<option value="
' . $objp->rowid . '"';
9540 $opt .= ($objp->rowid == $selected) ? ' selected' : '';
9543 $objRef = $objp->ref;
9544 if (!empty($filterkey) && $filterkey != '') {
9545 $objRef = preg_replace('/(' . preg_quote($filterkey, '/') . ')/i', '<strong>$1</strong>', $objRef, 1);
9548 $opt .= "</option>\n
";
9549 $optJson = array('key' => $outkey, 'value' => $outref, 'type' => $outtype);
9571 public function selectProjects($selected = '', $htmlname = 'projectid', $filtertype = '', $limit = 0, $status = 1, $selected_input_value = '', $hidelabel = 0, $ajaxoptions = array(), $socid = 0, $showempty = '1', $forcecombo = 0, $morecss = '', $selected_combinations = null, $nooutput = 0)
9573 global $langs, $conf;
9578 if (is_null($ajaxoptions)) {
9579 $ajaxoptions = array();
9582 if (!empty($conf->use_javascript_ajax) && getDolGlobalString('TICKET_USE_SEARCH_TO_SELECT')) {
9585 if ($selected && empty($selected_input_value)) {
9586 require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
9587 $projecttmpselect = new Project($this->db);
9588 $projecttmpselect->fetch((int) $selected);
9589 $selected_input_value = $projecttmpselect->ref;
9590 unset($projecttmpselect);
9594 $out .= ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT . '/projet/ajax/projects.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 1, $ajaxoptions);
9596 if (empty($hidelabel)) {
9597 $out .= $langs->trans("RefOrLabel
") . ' : ';
9598 } elseif ($hidelabel > 1) {
9599 $placeholder = ' placeholder="' . $langs->trans("RefOrLabel") . '"';
9600 if ($hidelabel == 2) {
9601 $out .= img_picto($langs->trans("Search
"), 'search');
9604 $out .= '<input type="text
" class="minwidth100
" name="search_
' . $htmlname . '" id="search_
' . $htmlname . '" value="' . $selected_input_value . '"' . $placeholder . ' ' . (getDolGlobalString('PRODUCT_SEARCH_AUTOFOCUS') ? 'autofocus' : '') . ' />';
9605 if ($hidelabel == 3) {
9606 $out .= img_picto($langs->trans("Search
"), 'search');
9609 $out .= $this->selectProjectsList($selected, $htmlname, $filtertype, $limit, '', $status, 0, $showempty, $forcecombo, $morecss);
9612 if (empty($nooutput)) {
9636 public function selectProjectsList($selected = '', $htmlname = 'projectid', $filtertype = '', $limit = 20, $filterkey = '', $status = 1, $outputmode = 0, $showempty = '1', $forcecombo = 0, $morecss = '')
9638 global $langs, $conf;
9641 $outarray = array();
9643 $selectFields = " p.rowid, p.ref
";
9646 $sql .= $this->db->sanitize($selectFields, 0, 0, 1);
9647 $sql .= " FROM
" . $this->db->prefix() . "projet as p
";
9648 $sql .= ' WHERE p.entity IN (' . getEntity('project') . ')';
9650 // Add criteria on ref/label
9651 if ($filterkey != '') {
9653 $prefix = !getDolGlobalString('TICKET_DONOTSEARCH_ANYWHERE') ? '%' : ''; // Can use index if PRODUCT_DONOTSEARCH_ANYWHERE is on
9654 // For natural search
9655 $search_crit = explode(' ', $filterkey);
9657 if (count($search_crit) > 1) {
9660 foreach ($search_crit as $crit) {
9664 $sql .= "p.ref LIKE
'" . $this->db->escape($prefix . $crit) . "%'";
9668 if (count($search_crit) > 1) {
9674 $sql .= $this->db->plimit($limit, 0);
9676 // Build output string
9677 dol_syslog(get_class($this) . "::selectProjectsList search projects
", LOG_DEBUG);
9678 $result = $this->db->query($sql);
9680 require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
9681 require_once DOL_DOCUMENT_ROOT . '/core/lib/project.lib.php';
9683 $num = $this->db->num_rows($result);
9688 include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
9689 $out .= ajax_combobox($htmlname, $events, getDolGlobalInt('PROJECT_USE_SEARCH_TO_SELECT'));
9692 $out .= '<select class="flat
' . ($morecss ? ' ' . $morecss : '') . '" name="' . $htmlname . '" id="' . $htmlname . '">';
9695 // Do not use textifempty = ' ' or ' ' here, or search on key will search on ' key'.
9696 //if (!empty($conf->use_javascript_ajax) || $forcecombo) $textifempty='';
9697 if (getDolGlobalString('PROJECT_USE_SEARCH_TO_SELECT')) {
9698 if ($showempty && !is_numeric($showempty)) {
9699 $textifempty = $langs->trans($showempty);
9701 $textifempty .= $langs->trans("All
");
9704 if ($showempty && !is_numeric($showempty)) {
9705 $textifempty = $langs->trans($showempty);
9709 $out .= '<option value="0
" selected>' . $textifempty . '</option>';
9713 while ($num && $i < $num) {
9716 $objp = $this->db->fetch_object($result);
9718 $this->constructProjectListOption($objp, $opt, $optJson, $selected, $filterkey);
9720 // "key
" value of json key array is used by jQuery automatically as selected value
9721 // "label
" value of json key array is used by jQuery automatically as text for combo box
9723 array_push($outarray, $optJson);
9728 $out .= '</select>';
9730 $this->db->free($result);
9732 if (empty($outputmode)) {
9737 dol_print_error($this->db);
9756 protected function constructProjectListOption(&$objp, &$opt, &$optJson, $selected, $filterkey = '')
9762 $label = $objp->label;
9764 $outkey = $objp->rowid;
9765 $outref = $objp->ref;
9766 $outlabel = $objp->label;
9767 $outtype = $objp->fk_product_type;
9769 $opt = '<option value="
' . $objp->rowid . '"';
9770 $opt .= ($objp->rowid == $selected) ? ' selected' : '';
9773 $objRef = $objp->ref;
9774 if (!empty($filterkey) && $filterkey != '') {
9775 $objRef = preg_replace('/(' . preg_quote($filterkey, '/') . ')/i', '<strong>$1</strong>', (string) $objRef, 1);
9778 $opt .= "</option>\n
";
9779 $optJson = array('key' => $outkey, 'value' => $outref, 'type' => $outtype);
9803 public function selectMembers($selected = '', $htmlname = 'adherentid', $filtertype = '', $limit = 0, $status = 1, $selected_input_value = '', $hidelabel = 0, $ajaxoptions = array(), $socid = 0, $showempty = '1', $forcecombo = 0, $morecss = '', $selected_combinations = null, $nooutput = 0, $excludeids = array())
9805 global $langs, $conf;
9810 if (is_null($ajaxoptions)) {
9811 $ajaxoptions = array();
9814 if (!empty($conf->use_javascript_ajax) && getDolGlobalString('TICKET_USE_SEARCH_TO_SELECT')) {
9817 if ($selected && empty($selected_input_value)) {
9818 require_once DOL_DOCUMENT_ROOT . '/adherents/class/adherent.class.php';
9819 $adherenttmpselect = new Adherent($this->db);
9820 $adherenttmpselect->fetch((int) $selected);
9821 $selected_input_value = $adherenttmpselect->ref;
9822 unset($adherenttmpselect);
9827 $out .= ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT . '/adherents/ajax/adherents.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 1, $ajaxoptions);
9829 if (empty($hidelabel)) {
9830 $out .= $langs->trans("RefOrLabel
") . ' : ';
9831 } elseif ($hidelabel > 1) {
9832 $placeholder = ' placeholder="' . $langs->trans("RefOrLabel") . '"';
9833 if ($hidelabel == 2) {
9834 $out .= img_picto($langs->trans("Search
"), 'search');
9837 $out .= '<input type="text
" class="minwidth100
" name="search_
' . $htmlname . '" id="search_
' . $htmlname . '" value="' . $selected_input_value . '"' . $placeholder . ' ' . (getDolGlobalString('PRODUCT_SEARCH_AUTOFOCUS') ? 'autofocus' : '') . ' />';
9838 if ($hidelabel == 3) {
9839 $out .= img_picto($langs->trans("Search
"), 'search');
9844 $out .= $this->selectMembersList($selected, $htmlname, $filtertype, $limit, $filterkey, $status, 0, $showempty, $forcecombo, $morecss, $excludeids);
9847 if (empty($nooutput)) {
9872 public function selectMembersList($selected = '', $htmlname = 'adherentid', $filtertype = '', $limit = 20, $filterkey = '', $status = 1, $outputmode = 0, $showempty = '1', $forcecombo = 0, $morecss = '', $excludeids = array())
9874 global $langs, $conf;
9877 $outarray = array();
9879 $selectFields = " p.rowid, p.ref, p.firstname, p.lastname, p.fk_adherent_type
";
9882 $sql .= $this->db->sanitize($selectFields, 0, 0, 1);
9883 $sql .= " FROM
" . $this->db->prefix() . "adherent as p
";
9884 $sql .= ' WHERE p.entity IN (' . getEntity('adherent') . ')';
9886 // Add criteria on ref/label
9887 if ($filterkey != '') {
9889 $prefix = !getDolGlobalString('MEMBER_DONOTSEARCH_ANYWHERE') ? '%' : ''; // Can use index if PRODUCT_DONOTSEARCH_ANYWHERE is on
9890 // For natural search
9891 $search_crit = explode(' ', $filterkey);
9893 if (count($search_crit) > 1) {
9896 foreach ($search_crit as $crit) {
9900 $sql .= "(p.firstname LIKE
'" . $this->db->escape($prefix . $crit) . "%'";
9901 $sql .= " OR p.lastname LIKE
'" . $this->db->escape($prefix . $crit) . "%')
";
9904 if (count($search_crit) > 1) {
9909 if ($status != -1) {
9910 $sql .= ' AND statut = ' . ((int) $status);
9912 if (!empty($excludeids)) {
9913 $sql .= " AND p.rowid NOT IN (
" . $this->db->sanitize(implode(',', $excludeids)) . ")
";
9915 $sql .= $this->db->plimit($limit, 0);
9917 // Build output string
9918 dol_syslog(get_class($this) . "::selectMembersList search adherents
", LOG_DEBUG);
9919 $result = $this->db->query($sql);
9921 require_once DOL_DOCUMENT_ROOT . '/adherents/class/adherent.class.php';
9922 require_once DOL_DOCUMENT_ROOT . '/core/lib/member.lib.php';
9924 $num = $this->db->num_rows($result);
9929 include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
9930 $out .= ajax_combobox($htmlname, $events, getDolGlobalInt('PROJECT_USE_SEARCH_TO_SELECT'));
9933 $out .= '<select class="flat
' . ($morecss ? ' ' . $morecss : '') . '" name="' . $htmlname . '" id="' . $htmlname . '">';
9936 // Do not use textifempty = ' ' or ' ' here, or search on key will search on ' key'.
9937 //if (!empty($conf->use_javascript_ajax) || $forcecombo) $textifempty='';
9938 if (getDolGlobalString('PROJECT_USE_SEARCH_TO_SELECT')) {
9939 if ($showempty && !is_numeric($showempty)) {
9940 $textifempty = $langs->trans($showempty);
9942 $textifempty .= $langs->trans("All
");
9945 if ($showempty && !is_numeric($showempty)) {
9946 $textifempty = $langs->trans($showempty);
9950 $out .= '<option value="-1
" selected>' . $textifempty . '</option>';
9954 while ($num && $i < $num) {
9957 $objp = $this->db->fetch_object($result);
9959 $this->constructMemberListOption($objp, $opt, $optJson, $selected, $filterkey);
9962 // "key
" value of json key array is used by jQuery automatically as selected value
9963 // "label
" value of json key array is used by jQuery automatically as text for combo box
9965 array_push($outarray, $optJson);
9970 $out .= '</select>';
9972 $this->db->free($result);
9974 if (empty($outputmode)) {
9979 dol_print_error($this->db);
9996 protected function constructMemberListOption(&$objp, &$opt, &$optJson, $selected, $filterkey = '')
10002 $outkey = $objp->rowid;
10003 $outlabel = dolGetFirstLastname($objp->firstname, $objp->lastname);
10004 $outtype = $objp->fk_adherent_type;
10006 $opt = '<option value="
' . $objp->rowid . '"';
10007 $opt .= ($objp->rowid == $selected) ? ' selected' : '';
10009 if (!empty($filterkey) && $filterkey != '') {
10010 $outlabel = preg_replace('/(' . preg_quote($filterkey, '/') . ')/i', '<strong>$1</strong>', $outlabel, 1);
10013 $opt .= "</option>\n
";
10015 $optJson = array('key' => $outkey, 'value' => $outlabel, 'type' => $outtype);
10039 public function selectForForms($objectdesc, $htmlname, $preSelectedValue, $showempty = '', $searchkey = '', $placeholder = '', $morecss = '', $moreparams = '', $forcecombo = 0, $disabled = 0, $selected_input_value = '', $objectfield = '')
10041 global $conf, $extrafields, $user, $hookmanager, $action;
10043 // Example of common usage for a link to a thirdparty
10045 // We got this in a modulebuilder form of "
MyObject" of module "mymodule
".
10046 // When ->fields is array( ... "fk_soc
" => array("type"=>"integer:
Societe:societe/
class/societe.class.php:1:((
status:=:1) AND (entity:IN:__SHARED_ENTITIES__))
" ...), we have
10047 // $objectdesc = 'Societe'
10048 // $objectfield = Method 1: 'myobject@mymodule:fk_soc' ('fk_soc' is code to retrieve myobject->fields['fk_soc'])
10049 // Method 2 recommended (it can be the array): array("type"=>"integer:
Societe:societe/class/societe.class.php:1:((
status:=:1) AND (entity:IN:__SHARED_ENTITIES__))
" ...)
10051 // We got this when showing an extrafields on resource that is a link to societe
10052 // When extrafields 'link_to_societe' for object Resource is 'link' to 'Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))', we have
10053 // $objectdesc = 'Societe'
10054 // $objectfield = Method 1: 'resource:options_link_to_societe'
10055 // Method 2 recommended (it can be the array): array("type"=>'Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))" ...)
10064 $objectdescorig = $objectdesc;
10066 $InfoFieldList = array();
10071 if (is_array($objectfield)) {
10072 $objectdesc = $objectfield[
'type'];
10073 $objectdesc = preg_replace(
'/^integer[^:]*:/',
'', $objectdesc);
10074 } elseif ($objectfield) {
10076 $tmparray = explode(
':', $objectfield);
10079 $objectforfieldstmp = fetchObjectByElement(0, strtolower($tmparray[0]));
10081 if (is_object($objectforfieldstmp)) {
10085 if (preg_match(
'/^options_(.*)$/', $tmparray[1], $reg)) {
10089 $extrafields->fetch_name_optionals_label($objectforfieldstmp->table_element);
10091 if (!empty($extrafields->attributes[$objectforfieldstmp->table_element][
'type'][$key]) && $extrafields->attributes[$objectforfieldstmp->table_element][
'type'][$key] ==
'link') {
10092 if (!empty($extrafields->attributes[$objectforfieldstmp->table_element][
'param'][$key][
'options'])) {
10093 $tmpextrafields = array_keys($extrafields->attributes[$objectforfieldstmp->table_element][
'param'][$key][
'options']);
10094 $objectdesc = $tmpextrafields[0];
10099 if (array_key_exists($tmparray[1], $objectforfieldstmp->fields)) {
10100 $objectdesc = $objectforfieldstmp->fields[$tmparray[1]][
'type'];
10101 $objectdesc = preg_replace(
'/^integer[^:]*:/',
'', $objectdesc);
10112 $InfoFieldList = explode(
":", $objectdesc, 4);
10113 $vartmp = (empty($InfoFieldList[3]) ?
'' : $InfoFieldList[3]);
10115 if (preg_match(
'/^.*:(\w*)$/', $vartmp, $reg)) {
10116 $InfoFieldList[4] = $reg[1];
10118 $InfoFieldList[3] = preg_replace(
'/:\w*$/',
'', $vartmp);
10120 $classname = $InfoFieldList[0];
10121 $classpath = empty($InfoFieldList[1]) ?
'' : $InfoFieldList[1];
10123 $filter = empty($InfoFieldList[3]) ?
'' : $InfoFieldList[3];
10124 $sortfield = empty($InfoFieldList[4]) ?
'' : $InfoFieldList[4];
10127 $objecttmp = fetchObjectByElement(0, strtolower($InfoFieldList[0]));
10130 if (empty($objecttmp) && !empty($classpath)) {
10133 if ($classname && class_exists($classname)) {
10134 $objecttmp =
new $classname($this->db);
10141 $sharedentities = (is_object($objecttmp) && property_exists($objecttmp,
'element')) ?
getEntity($objecttmp->element) : strtolower($classname);
10142 $filter = str_replace(
10143 array(
'__ENTITY__',
'__SHARED_ENTITIES__',
'__USER_ID__'),
10144 array(
$conf->entity, $sharedentities, $user->id),
10148 if (!is_object($objecttmp)) {
10149 dol_syslog(
'selectForForms: Error bad setup of field objectdescorig=' . $objectdescorig.
', objectfield='.(is_array($objectfield) ?
'array' : $objectfield).
', objectdesc='.$objectdesc, LOG_WARNING);
10150 return 'selectForForms: Error bad setup of field objectdescorig=' . $objectdescorig.
', objectfield='.(is_array($objectfield) ?
'array' : $objectfield).
', objectdesc='.$objectdesc;
10152 '@phan-var-force CommonObject $objecttmp';
10155 $prefixforautocompletemode = $objecttmp->element;
10156 if ($prefixforautocompletemode ==
'societe') {
10157 $prefixforautocompletemode =
'company';
10159 if ($prefixforautocompletemode ==
'product') {
10160 $prefixforautocompletemode =
'produit';
10163 $confkeyforautocompletemode = strtoupper($prefixforautocompletemode) .
'_USE_SEARCH_TO_SELECT';
10165 dol_syslog(get_class($this) .
"::selectForForms filter=" . $filter, LOG_DEBUG);
10173 if ($preSelectedValue && empty($selected_input_value)) {
10174 $objecttmp->fetch($preSelectedValue);
10175 $selected_input_value = ($prefixforautocompletemode ==
'company' ? $objecttmp->name : $objecttmp->ref);
10177 $oldValueForShowOnCombobox = 0;
10178 foreach ($objecttmp->fields as $fieldK => $fielV) {
10179 if (!array_key_exists(
'showoncombobox', $fielV) || !$fielV[
'showoncombobox'] || empty($objecttmp->$fieldK)) {
10183 if (!$oldValueForShowOnCombobox) {
10184 $selected_input_value =
'';
10187 $selected_input_value .= $oldValueForShowOnCombobox ?
' - ' :
'';
10188 $selected_input_value .= $objecttmp->$fieldK;
10189 $oldValueForShowOnCombobox = empty($fielV[
'showoncombobox']) ? 0 : $fielV[
'showoncombobox'];
10194 $urlforajaxcall = DOL_URL_ROOT .
'/core/ajax/selectobject.php';
10195 $urloption =
'htmlname=' . urlencode($htmlname) .
'&outjson=1&objectdesc=' . urlencode($objectdescorig) . (is_scalar($objectfield) ?
'&objectfield='.urlencode($objectfield) :
'') . ($sortfield ?
'&sortfield=' . urlencode($sortfield) :
'');
10199 $parameters = array(
10200 'urloption' => $urloption,
10201 'object' => $objecttmp,
10202 'htmlname' => $htmlname,
10203 'filter' => $filter,
10204 'searchkey' => $searchkey,
10206 $reshook = $hookmanager->executeHooks(
'selectForFormsListUrl', $parameters, $objecttmp, $action);
10207 if (!empty($reshook)) {
10208 $urloption = $hookmanager->resPrint;
10209 $hookmanager->resPrint =
'';
10214 $out .=
'<!-- force css to be higher than dialog popup --><style type="text/css">.ui-autocomplete { z-index: 1010; }</style>';
10215 $out .=
'<input type="text" class="' . $morecss .
'"' . ($disabled ?
' disabled="disabled"' :
'') .
' name="search_' . $htmlname .
'" id="search_' . $htmlname .
'" value="' . $selected_input_value .
'"' . ($placeholder ?
' placeholder="' .
dol_escape_htmltag($placeholder) .
'"' :
'') .
' />';
10218 $out .= $this->selectForFormsList($objecttmp, $htmlname, $preSelectedValue, $showempty, $searchkey, $placeholder, $morecss, $moreparams, $forcecombo, 0, $disabled, $sortfield, $filter);
10246 public function selectForFormsList($objecttmp, $htmlname, $preselectedvalue, $showempty =
'', $searchkey =
'', $placeholder =
'', $morecss =
'', $moreparams =
'', $forcecombo = 0, $outputmode = 0, $disabled = 0, $sortfield =
'', $filter =
'', $sortorder =
'ASC')
10248 global $langs, $user, $hookmanager;
10252 $prefixforautocompletemode = $objecttmp->element;
10253 if ($prefixforautocompletemode ==
'societe') {
10254 $prefixforautocompletemode =
'company';
10256 $confkeyforautocompletemode = strtoupper($prefixforautocompletemode) .
'_USE_SEARCH_TO_SELECT';
10258 $fieldstoshow =
'';
10259 if (!empty($objecttmp->fields)) {
10260 $tmpfieldstoshow =
'';
10261 foreach ($objecttmp->fields as $key => $val) {
10262 if (! (
int)
dol_eval((
string) $val[
'enabled'], 1, 1,
'1')) {
10265 if (!empty($val[
'showoncombobox'])) {
10266 $tmpfieldstoshow .= ($tmpfieldstoshow ?
',' :
'') .
't.' . $key;
10269 if ($tmpfieldstoshow) {
10270 $fieldstoshow = $tmpfieldstoshow;
10272 } elseif ($objecttmp->element ===
'category') {
10273 $fieldstoshow =
't.label';
10276 $objecttmp->fields[
'ref'] = array(
'type' =>
'varchar(30)',
'label' =>
'Ref',
'enabled' => 1,
'position' => 10,
'visible' => 4,
'showoncombobox' => 1);
10279 if (empty($fieldstoshow)) {
10280 if (!empty($objecttmp->parent_element)) {
10281 $fieldstoshow =
'o.ref';
10282 if (empty($sortfield)) {
10283 $sortfield =
'o.ref';
10285 if (in_array($objecttmp->element, [
'commandedet',
'propaldet',
'facturedet',
'expeditiondet'])) {
10286 $fieldstoshow .=
',p.ref AS p_ref,p.label,t.description';
10287 $sortfield .=
', p.ref';
10289 } elseif (isset($objecttmp->fields[
'ref'])) {
10290 $fieldstoshow =
't.ref';
10292 $langs->load(
"errors");
10293 $this->error = $langs->trans(
"ErrorNoFieldWithAttributeShowoncombobox");
10294 return $langs->trans(
'ErrorNoFieldWithAttributeShowoncombobox');
10299 $outarray = array();
10300 $tmparray = array();
10304 $sanitizedfieldstoshow = $fieldstoshow;
10307 $sql =
"SELECT t.rowid, " . $sanitizedfieldstoshow .
" FROM " . $this->db->prefix() . $this->db->sanitize($objecttmp->table_element) .
" as t";
10308 if (!empty($objecttmp->isextrafieldmanaged)) {
10309 $extrafieldTable = $objecttmp->table_element;
10310 if ($extrafieldTable ==
'categorie') {
10311 $extrafieldTable =
'categories';
10313 $sql .=
" LEFT JOIN " . $this->db->prefix() . $this->db->sanitize($extrafieldTable) .
"_extrafields as e ON t.rowid = e.fk_object";
10315 if (!empty($objecttmp->parent_element)) {
10316 '@phan-var-force CommonObjectLine $objecttmp';
10319 $sql .=
" INNER JOIN " . $this->db->prefix() . $this->db->sanitize($parent_properties[
'table_element']) .
" as o ON o.rowid = t.".$this->db->sanitize($objecttmp->fk_parent_attribute);
10321 if (!empty($objecttmp->parent_element) && in_array($objecttmp->parent_element, [
'commande',
'propal',
'facture',
'expedition'])) {
10322 $sql .=
" LEFT JOIN " . $this->db->prefix() .
"product as p ON p.rowid = t.fk_product";
10324 if (!empty($objecttmp->ismultientitymanaged)) {
10325 if ($objecttmp->ismultientitymanaged == 1) {
10328 if (!is_numeric($objecttmp->ismultientitymanaged)) {
10329 $tmparray = explode(
'@', $objecttmp->ismultientitymanaged);
10330 $sql .=
" INNER JOIN " . $this->db->prefix() . $this->db->sanitize($tmparray[1]) .
" as parenttable ON parenttable.rowid = t." . $this->db->sanitize($tmparray[0]);
10335 $parameters = array(
10336 'object' => $objecttmp,
10337 'htmlname' => $htmlname,
10338 'filter' => $filter,
10339 'searchkey' => $searchkey
10342 $reshook = $hookmanager->executeHooks(
'selectForFormsListWhere', $parameters);
10343 if (!empty($hookmanager->resPrint)) {
10344 $sql .= $hookmanager->resPrint;
10346 $sql .=
" WHERE 1=1";
10349 if (!empty($objecttmp->ismultientitymanaged)) {
10350 if ($objecttmp->ismultientitymanaged == 1) {
10351 $sql .=
" AND t.entity IN (" .
getEntity($objecttmp->element) .
")";
10353 if (!is_numeric($objecttmp->ismultientitymanaged)) {
10354 $sql .=
" AND parenttable.entity = t." . $this->db->sanitize($tmparray[0]);
10358 if ($objecttmp->ismultientitymanaged ===
'fk_soc@societe') {
10359 if (!$user->hasRight(
'societe',
'client',
'voir') && empty($user->socid)) {
10360 $sql .=
" AND EXISTS (SELECT sc.rowid FROM ".$this->db->prefix() .
"societe_commerciaux as sc";
10361 $sql .=
" WHERE sc.fk_soc = t.fk_soc AND sc.fk_user = ".((int) $user->id).
")";
10367 if (!empty($user->socid)) {
10368 if ($objecttmp->element ==
'societe') {
10369 $sql .=
" AND t.rowid = " . ((int) $user->socid);
10370 } elseif (!empty($objecttmp->fields[
'fk_soc']) || !empty($objecttmp->fields[
't.fk_soc']) || property_exists($objecttmp,
'fk_soc') || property_exists($objecttmp,
'socid')) {
10371 $sql .=
" AND t.fk_soc = " . ((int) $user->socid);
10372 } elseif (!empty($objecttmp->parent_element)) {
10373 $tmpparent = fetchObjectByElement(0, $objecttmp->parent_element,
'', 1);
10374 if (is_object($tmpparent) && (!empty($tmpparent->fields[
'fk_soc']) || !empty($tmpparent->fields[
't.fk_soc']) || property_exists($tmpparent,
'fk_soc') || property_exists($tmpparent,
'socid'))) {
10375 $sql .=
" AND o.fk_soc = " . ((int) $user->socid);
10380 $splittedfieldstoshow = explode(
',', $fieldstoshow);
10381 foreach ($splittedfieldstoshow as &$field2) {
10382 if (is_numeric($pos = strpos($field2,
' '))) {
10383 $field2 = substr($field2, 0, $pos);
10386 if ($searchkey !=
'') {
10391 $errormessage =
'';
10393 if ($errormessage) {
10394 return 'Error forging a SQL request from an universal criteria: ' . $errormessage;
10398 $sql .= $this->db->order($sortfield ? $sortfield : $fieldstoshow, $sortorder);
10403 $resql = $this->db->query($sql);
10406 $out .=
'<select id="' . $htmlname .
'" class="flat minwidth100' . ($morecss ?
' ' . $morecss :
'') .
'"' . ($disabled ?
' disabled="disabled"' :
'') . ($moreparams ?
' ' . $moreparams :
'') .
' name="' . $htmlname .
'">' .
"\n";
10409 $textifempty =
' ';
10413 if ($showempty && !is_numeric($showempty)) {
10414 $textifempty = $langs->trans($showempty);
10416 $textifempty .= $langs->trans(
"All");
10420 $out .=
'<option value="-1">' . $textifempty .
'</option>' .
"\n";
10423 $num = $this->db->num_rows($resql);
10426 while ($i < $num) {
10427 $obj = $this->db->fetch_object($resql);
10430 $tmparray = explode(
',', $fieldstoshow);
10431 $oldvalueforshowoncombobox = 0;
10432 foreach ($tmparray as $key => $val) {
10433 $val = preg_replace(
'/(t|p|o)\./',
'', $val);
10434 $label .= (($label && $obj->$val) ? ($oldvalueforshowoncombobox != $objecttmp->fields[$val][
'showoncombobox'] ?
' - ' :
' ') :
'');
10435 $labelhtml .= (($label && $obj->$val) ? ($oldvalueforshowoncombobox != $objecttmp->fields[$val][
'showoncombobox'] ?
' - ' :
' ') :
'');
10436 $label .= $obj->$val;
10437 $labelhtml .= $obj->$val;
10439 $oldvalueforshowoncombobox = empty($objecttmp->fields[$val][
'showoncombobox']) ? 0 : $objecttmp->fields[$val][
'showoncombobox'];
10441 if (empty($outputmode)) {
10442 if ($preselectedvalue > 0 && $preselectedvalue == $obj->rowid) {
10443 $out .=
'<option value="' . $obj->rowid .
'" selected data-html="' .
dol_escape_htmltag($labelhtml, 0, 0,
'', 0, 1) .
'">' .
dol_escape_htmltag($label, 0, 0,
'', 0, 1) .
'</option>';
10445 $out .=
'<option value="' . $obj->rowid .
'" data-html="' .
dol_escape_htmltag($labelhtml, 0, 0,
'', 0, 1) .
'">' .
dol_escape_htmltag($label, 0, 0,
'', 0, 1) .
'</option>';
10448 array_push($outarray, array(
'key' => $obj->rowid,
'value' => $label,
'label' => $label));
10452 if (($i % 10) == 0) {
10458 $out .=
'</select>' .
"\n";
10460 if (!$forcecombo) {
10461 include_once DOL_DOCUMENT_ROOT .
'/core/lib/ajax.lib.php';
10465 dol_print_error($this->db);
10468 $this->result = array(
'nbofelement' => $num);
10486 public static function radio($htmlName, $radioItems, $selected =
'', $moreGlobalParams = [])
10490 'disabled' =>
false,
10493 'name' => $htmlName,
10496 'labelIsHtml' => false
10503 if (!empty($radioItems)) {
10504 foreach ($radioItems as $key => $item) {
10506 if (!is_array($item)) {
10518 'value' => !isset($item[
'attr'][
'value']) ? $key :
'',
10528 if ((is_array($selected) && in_array($item[
'attr'][
'value'], $selected,
true)) || $selected === $item[
'attr'][
'value']) {
10529 $item[
'attr'][
'checked'] =
true;
10537 $text = $item[
'labelIsHtml'] ? $item[
'label'] : htmlspecialchars($item[
'label'], ENT_QUOTES | ENT_SUBSTITUTE);
10540 $out .=
'<label ' . $labelAttributes .
'><input ' . $inputAttributes .
' /> ' . $text .
'</label> ';
10571 public static function selectarray($htmlname, $array,
$id =
'', $show_empty = 0, $key_in_label = 0, $value_as_key = 0, $moreparam =
'', $translate = 0, $maxlen = 0, $disabled = 0, $sort =
'', $morecss =
'minwidth75', $addjscombo = 1, $moreparamonempty =
'', $disablebademail = 0, $nohtmlescape = 0)
10573 global
$conf, $langs;
10580 if ($value_as_key) {
10581 $array = array_combine($array, $array);
10584 '@phan-var-force array{label:string,data-html:string,disable?:int<0,1>,css?:string} $array';
10588 if ($addjscombo < 0) {
10595 $idname = str_replace(array(
'[',
']'), array(
'',
''), $htmlname);
10596 $out .=
'<select id="' . preg_replace(
'/^\./',
'', $idname) .
'" ' . ($disabled ?
'disabled="disabled" ' :
'') .
'class="flat ' . (preg_replace(
'/^\./',
'', $htmlname)) . ($morecss ?
' ' . $morecss :
'') .
' selectformat"';
10597 $out .=
' name="' . preg_replace(
'/^\./',
'', $htmlname) .
'" ' . ($moreparam ? $moreparam :
'');
10601 $textforempty =
' ';
10602 if (!empty(
$conf->use_javascript_ajax)) {
10603 $textforempty =
' ';
10605 if (!is_numeric($show_empty)) {
10606 $textforempty = $show_empty;
10608 $out .=
'<option class="optiongrey" ' . ($moreparamonempty ? $moreparamonempty .
' ' :
'') .
'value="' . (((
int) $show_empty) < 0 ? $show_empty : -1) .
'"' . (
$id == $show_empty ?
' selected' :
'') .
'>' .
dol_escape_htmltag($textforempty) .
'</option>' .
"\n";
10610 if (is_array($array)) {
10613 foreach ($array as $key => $value) {
10614 if (!is_array($value)) {
10615 $array[$key] = $langs->trans($value);
10617 $array[$key][
'label'] = $langs->trans($value[
'label']);
10622 if ($sort ==
'ASC') {
10624 } elseif ($sort ==
'DESC') {
10628 foreach ($array as $key => $tmpvalue) {
10629 if (is_array($tmpvalue)) {
10630 $value = $tmpvalue[
'label'];
10632 $disabled = empty($tmpvalue[
'disabled']) ?
'' :
' disabled';
10633 $style = empty($tmpvalue[
'css']) ?
'' :
' class="' . $tmpvalue[
'css'] .
'"';
10635 $value = $tmpvalue;
10640 if (!empty($disablebademail)) {
10641 if (($disablebademail == 1 && !preg_match(
'/<.+@.+>/', $value))
10642 || ($disablebademail == 2 && preg_match(
'/---/', $value))) {
10643 $disabled =
' disabled';
10644 $style =
' class="warning"';
10647 if ($key_in_label) {
10648 if (empty($nohtmlescape)) {
10651 $selectOptionValue = $key .
' - ' . ($maxlen ?
dol_trunc($value, $maxlen) : $value);
10654 if (empty($nohtmlescape)) {
10657 $selectOptionValue = $maxlen ?
dol_trunc($value, $maxlen) : $value;
10659 if ($value ==
'' || $value ==
'-') {
10660 $selectOptionValue =
' ';
10663 $out .=
'<option value="' . $key .
'"';
10664 $out .= $style . $disabled;
10665 $out .= is_array($tmpvalue) && !empty($tmpvalue[
'parent']) ?
' parent="' . dolPrintHTMLForAttribute($tmpvalue[
'parent']) .
'"' :
'';
10666 if (is_array(
$id)) {
10667 if (in_array($key,
$id) && !$disabled) {
10668 $out .=
' selected';
10672 if (
$id !=
'' && ((
$id == (
string) $key) || (
$id ==
'ifone' && count($array) == 1)) && !$disabled) {
10673 $out .=
' selected';
10677 if (is_array($tmpvalue)) {
10678 foreach ($tmpvalue as $keyforvalue => $valueforvalue) {
10679 if ($keyforvalue ==
'labelhtml') {
10680 $keyforvalue =
'data-html';
10682 if (preg_match(
'/^data-/', $keyforvalue)) {
10683 $out .=
' '.dol_escape_htmltag($keyforvalue).
'="'.
dol_escape_htmltag($valueforvalue).
'"';
10686 } elseif (!empty($nohtmlescape)) {
10691 $out .= $selectOptionValue;
10692 $out .=
"</option>\n";
10695 $out .=
"</select>";
10698 if ($addjscombo && $jsbeautify) {
10700 include_once DOL_DOCUMENT_ROOT .
'/core/lib/ajax.lib.php';
10701 $out .=
ajax_combobox($idname, array(), 0, 0,
'resolve', (((
int) $show_empty) < 0 ? (
string) $show_empty :
'-1'), $morecss);
10725 public static function selectArrayAjax($htmlname, $url,
$id =
'', $moreparam =
'', $moreparamtourl =
'', $disabled = 0, $minimumInputLength = 1, $morecss =
'', $callurlonselect = 0, $placeholder =
'', $acceptdelayedhtml = 0)
10728 global $delayedhtmlcontent;
10731 if (!
getDolGlobalString(
'MAIN_USE_JQUERY_MULTISELECT') && !defined(
'REQUIRE_JQUERY_MULTISELECT')) {
10735 $out =
'<select type="text" class="' . $htmlname . ($morecss ?
' ' . $morecss :
'') .
'" ' . ($moreparam ? $moreparam .
' ' :
'') .
'name="' . $htmlname .
'"></select>';
10738 if (!empty(
$conf->use_javascript_ajax)) {
10739 $tmpplugin =
'select2';
10740 $outdelayed =
"\n" .
'<!-- JS CODE TO ENABLE ' . $tmpplugin .
' for id ' . $htmlname .
' -->
10741 <script nonce="' .
getNonce() .
'">
10742 $(document).ready(function () {
10744 ' . ($callurlonselect ?
'var saveRemoteData = [];' :
'') .
'
10746 $(".' . $htmlname .
'").select2({
10749 url: "' . $url .
'",
10750 dataType: \'json\',
10752 data: function (params) {
10754 q: params.term, // search term
10758 processResults: function (data) {
10759 // parse the results into the format expected by Select2.
10760 // since we are using custom formatting functions we do not need to alter the remote JSON data
10761 //console.log(data);
10762 saveRemoteData = data;
10763 /* format json result for select2 */
10765 $.each( data, function( key, value ) {
10766 result.push({id: key, text: value.text});
10768 //return {results:[{id:\'none\', text:\'aa\'}, {id:\'rrr\', text:\'Red\'},{id:\'bbb\', text:\'Search a into projects\'}], more:false}
10769 //console.log(result);
10770 return {results: result, more: false}
10774 language: (typeof select2arrayoflanguage === \'undefined\') ? \'en\' : select2arrayoflanguage,
10775 containerCssClass: \':all:\', /* Line to add class from the original SELECT propagated to the new <span class="select2-selection...> tag */
10777 escapeMarkup:
function (markup) {
return markup; },
10778 minimumInputLength:
' . ((int) $minimumInputLength) . ',
10779 formatResult:
function (result, container, query, escapeMarkup) {
10780 return escapeMarkup(result.text);
10784 ' . ($callurlonselect ? '
10786 $(
".' . $htmlname . '").change(
function() {
10787 var selected = $(\
'.' .
dol_escape_js($htmlname) .
'\').val();
10788 console.log(
"We select in selectArrayAjax the entry "+selected)
10790 $.each( saveRemoteData,
function( key, value ) {
10791 if (key == selected)
10793 console.log(
"selectArrayAjax - Do a redirect to "+value.url)
10794 location.assign(value.url);
10803 if ($acceptdelayedhtml) {
10804 $delayedhtmlcontent .= $outdelayed;
10806 $out .= $outdelayed;
10830 public static function selectArrayFilter($htmlname, $array, $id = '
', $moreparam = '', $disableFiltering = 0, $disabled = 0, $minimumInputLength = 1, $morecss = '', $callurlonselect = 0, $placeholder = '', $acceptdelayedhtml = 0, $textfortitle = '')
10833 global $delayedhtmlcontent; // Will be used later outside of this function
10835 // TODO Use an internal dolibarr component instead of select2
10836 if (!getDolGlobalString('MAIN_USE_JQUERY_MULTISELECT
') && !defined('REQUIRE_JQUERY_MULTISELECT
')) {
10840 $out = '<select
type=
"text"'.($textfortitle ? ' title=
"'.dol_escape_htmltag($textfortitle).'"' : '').' id=
"'.$htmlname.'" class=
"'.$htmlname.($morecss ? ' ' . $morecss : '').'"'.($moreparam ? ' '.$moreparam : '').' name=
"'.$htmlname.'"><option></option></select>
';
10842 $formattedarrayresult = array();
10844 foreach ($array as $key => $value) {
10845 $o = new stdClass();
10847 $o->text = $value['text
'];
10848 $o->url = $value['url
'];
10849 $formattedarrayresult[] = $o;
10853 if (!empty($conf->use_javascript_ajax)) {
10854 $tmpplugin = 'select2
';
10855 $outdelayed = "\n" . '<!-- JS CODE TO ENABLE
' . $tmpplugin . ' for id ' . $htmlname . ' -->
10856 <script nonce=
"' . getNonce() . '">
10857 $(document).ready(
function () {
10858 var data =
' . json_encode($formattedarrayresult) . ';
10860 ' . ($callurlonselect ? 'var saveRemoteData =
' . json_encode($array) . ';
' : '') . '
10864 language: (typeof select2arrayoflanguage === \
'undefined\') ? \'en\' : select2arrayoflanguage,
10865 containerCssClass: \':all:\', /* Line to add class from the original SELECT propagated to the new <span class="select2-selection...> tag */
10867 escapeMarkup:
function (markup) {
return markup; },
10868 minimumInputLength:
' . ((int) $minimumInputLength) . ',
10869 formatResult:
function (result, container, query, escapeMarkup) {
10870 return escapeMarkup(result.text);
10872 matcher:
function (params, data) {
10874 if(! data.id)
return null;
';
10876 if ($callurlonselect) {
10877 // We forge the url with 'sall=
'
10880 var urlBase = data.url;
10881 var separ = urlBase.indexOf(
"?") >= 0 ?
"&" :
"?";
10884 saveRemoteData[data.id].url = urlBase + separ +
"search_all=" + encodeURIComponent(params.term.replace(/\
"/g, ""));';
10887 if (!$disableFiltering) {
10890 if(data.text.match(new RegExp(params.term))) {
10905 ' . ($callurlonselect ? '
10906 /* Code to execute a GET when we select a value */
10907 $(\'.' . dol_escape_js($htmlname) . '\').change(function() {
10908 var selected = $(\'.' . dol_escape_js($htmlname) . '\').val();
10909 console.log("We select
"+selected)
10911 $(\'.' . dol_escape_js($htmlname) . '\').val(""); /* reset visible combo value */
10912 $.each( saveRemoteData, function( key, value ) {
10913 if (key == selected)
10915 console.log("selectArrayFilter - Do a redirect to
"+value.url)
10916 location.assign(value.url);
10925 if ($acceptdelayedhtml) {
10926 $delayedhtmlcontent .= $outdelayed;
10928 $out .= $outdelayed;
10951 public static function multiselectarray($htmlname, $array, $selected = array(), $key_in_label = 0, $value_as_key = 0, $morecss = '', $translate = 0, $width = 0, $moreattrib = '', $nu = '', $placeholder = '', $addjscombo = -1)
10953 global $conf, $langs;
10956 if ($addjscombo < 0) {
10957 if (!getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
10964 $useenhancedmultiselect = 0;
10965 if (!empty($conf->use_javascript_ajax) && !defined('MAIN_DO_NOT_USE_JQUERY_MULTISELECT') && (getDolGlobalString('MAIN_USE_JQUERY_MULTISELECT') || defined('REQUIRE_JQUERY_MULTISELECT'))) {
10967 $useenhancedmultiselect = 1; // Use the js multiselect in one line. Possible only if $addjscombo not 0.
10971 $out .= '<span class="multiselectarray
'.$htmlname.'">';
10973 // We need a hidden field because when using the multiselect, if we unselect all, there is no
10974 // variable submitted at all, so no way to make a difference between variable not submitted and variable
10975 // submitted to nothing.
10976 $out .= '<input type="hidden
" name="'.$htmlname.'_multiselect
" value="1
">';
10977 // Output select component
10978 $out .= '<select id="'.$htmlname.'" class="multiselect
' . ($useenhancedmultiselect ? ' multiselectononeline
' : '') . ($morecss ? ' ' . $morecss : '') . '" multiple name="' . $htmlname . '[]
"' . ($moreattrib ? ' ' . $moreattrib : '') . ($width ? ' style="width:
' . (preg_match('/%/
', (string) $width) ? $width : $width . 'px
') . '"' : '') . '>' . "\n
";
10979 if (is_array($array) && !empty($array)) {
10980 if ($value_as_key) {
10981 $array = array_combine($array, $array);
10984 if (!empty($array)) {
10985 foreach ($array as $key => $value) {
10987 $tmplabel = $value;
10988 $tmplabelhtml = '';
10992 if (is_array($value) && array_key_exists('id', $value) && array_key_exists('label', $value)) {
10993 $tmpkey = $value['id'];
10994 $tmplabel = empty($value['label']) ? '' : $value['label'];
10995 $tmplabelhtml = empty($value['labelhtml']) ? (empty($value['data-html']) ? '' : $value['data-html']) : $value['labelhtml'];
10996 $tmpcolor = empty($value['color']) ? '' : $value['color'];
10997 $tmppicto = empty($value['picto']) ? '' : $value['picto'];
10998 $tmpdisabled = empty($value['disabled']) ? '' : $value['disabled'];
11000 $newval = ($translate ? $langs->trans($tmplabel) : $tmplabel);
11001 $newval = ($key_in_label ? $tmpkey . ' - ' . $newval : $newval);
11003 $tmplabelhtml = ($translate ? $langs->trans($tmplabelhtml) : $tmplabelhtml);
11004 $tmplabelhtml = ($key_in_label ? $tmpkey . ' - ' . $tmplabelhtml : $tmplabelhtml);
11006 $out .= '<option value="' . $tmpkey . '"';
11007 if (is_array($selected) && !empty($selected) && in_array((string) $tmpkey, $selected) && ((string) $tmpkey != '')) {
11008 $out .= ' selected';
11010 $out .= is_array($value) && array_key_exists('parent', $value) && !empty($value['parent']) ? ' parent="' . dolPrintHTMLForAttribute($value['parent
']) . '"' : '';
11011 if ($tmpdisabled) {
11014 if (!empty($tmplabelhtml)) {
11015 $out .= ' data-html="' . dolPrintHTMLForAttribute($tmplabelhtml) . '"';
11017 $tmplabelhtml = ($tmppicto ? img_picto('', $tmppicto, 'class="pictofixedwidth
" style="color: #
' . $tmpcolor . '"') : '') . $newval;
11018 $out .= ' data-html="' . dolPrintHTMLForAttribute($tmplabelhtml) . '"';
11021 $out .= dol_htmlentitiesbr($newval);
11022 $out .= '</option>' . "\n
";
11026 $out .= '</select>' . "\n
";
11030 // Add code for jquery to use multiselect
11031 if (!empty($conf->use_javascript_ajax) && getDolGlobalString('MAIN_USE_JQUERY_MULTISELECT') || defined('REQUIRE_JQUERY_MULTISELECT')) {
11032 $out .= "\n
" . '<!-- JS CODE TO ENABLE select for id ' . $htmlname . ', addjscombo=' . $addjscombo . ' -->';
11033 $out .= "\n
" . '<script nonce="' . getNonce() . '">' . "\n
";
11034 if ($addjscombo == 1) {
11035 $moreselect2theme = ($morecss ? dol_escape_js(' '.$morecss) : '');
11036 $moreselect2theme = preg_replace('/widthcentpercentminus[^\s]*/', '', $moreselect2theme);
11038 $widthTypeOfAutocomplete = 'resolve';
11040 $tmpplugin = getDolGlobalString('MAIN_USE_JQUERY_MULTISELECT', (defined('REQUIRE_JQUERY_MULTISELECT') ? constant('REQUIRE_JQUERY_MULTISELECT') : 'select2'));
11042 // If property data-html set, we decode html entities and use this.
11043 // Note that HTML content must have been sanitized from js with dol_escape_htmltag(xxx, 0, 0, '', 0, 1) when building the select option.
11044 // TODO Move this into common js ?
11045 $out .= 'function formatResult(record, container) {' . "\n
";
11046 $out .= ' if ($(record.element).attr("data-html
") != undefined && typeof htmlEntityDecodeJs === "function
") {';
11047 $out .= ' return htmlEntityDecodeJs($(record.element).attr("data-html
"));';
11049 $out .= ' return record.text;';
11050 $out .= '}' . "\n
";
11052 $out .= 'function formatSelection(record) {' . "\n
";
11053 $out .= ' return record.text;';
11054 $out .= '}' . "\n
";
11056 // Load the select2 enhancer
11057 //$out .= 'console.log(\'addjscombo=1 for htmlname=' . dol_escape_js($htmlname) . '\');';
11058 $out .= '$(document).ready(function () {
11059 $(\'#' . dol_escape_js($htmlname) . '\').' . $tmpplugin . '({';
11060 // when $morecss contains 'onrightofpage', the select2 component must also be inside a parent with class="parentonrightofpage
"
11061 if (preg_match('/onrightofpage/', $morecss)) { // In this cas, htmlname must be an ID not a class.
11062 $out .= ' dropdownAutoWidth: true, ';
11063 $out .= ' dropdownParent: $(\'#'.$htmlname.'\').parent(), ';
11065 if ($placeholder) {
11069 text: \''.dol_escape_js($placeholder).'\'
11072 $out .= ' dir: \'ltr\',
11073 width: \''.dol_escape_js($widthTypeOfAutocomplete).'\', /* off or resolve */
11074 theme: \'default' . dol_escape_js($moreselect2theme) . '\', /* to add css on generated html components */
11075 containerCssClass: \':all:\', /* Line to add class of origin SELECT propagated to the new <span class="select2-selection...> tag (ko with multiselect) */
11076 selectionCssClass: \
':all:\', /* Line to add class of origin SELECT propagated to the new <span class="select2-selection...> tag */
11077 dropdownCssClass: \'dol-dropdown-dialog dol-dropdown-dialogmulti\', /* Line to add class on the new <span class="select2-selection...> tag (ok with multiselect). Need full version of select2. */
11078 // Specify format function for dropdown item
11079 formatResult: formatResult,
11080 templateResult: formatResult, /* For 4.0 */
11081 escapeMarkup: function (markup) { return markup; }, // let our custom formatter work
11082 // Specify format function for selected item
11083 formatSelection: formatSelection,
11084 templateSelection: formatSelection, /* For 4.0 */
11085 language: (typeof select2arrayoflanguage === \'undefined\') ? \'en\' : select2arrayoflanguage
11088 /* Add also morecss to the css .select2 that is after the #htmlname, for component that are shown dynamically after load, because select2 set
11089 the size only if component is not hidden by default on load */
11092 } elseif ($addjscombo == 2 && !defined(
'DISABLE_MULTISELECT')) {
11096 $out .=
'console.log(\'addjscombo=2 for htmlname=' .
dol_escape_js($htmlname) .
'\');
';
11097 $out .= '$(document).ready(
function () {
11099 containerHTML: \
'<div class="multi-select-container">\',
11100 menuHTML: \'<div class="multi-select-menu">\',
11101 buttonHTML: \'<span class="multi-select-button ' .
dol_escape_js($morecss) .
'">\',
11102 menuItemHTML: \'<label class="multi-select-menuitem">\',
11103 activeClass: \'multi-select-container--open\',
11108 $out .= '</script>
';
11128 public static function multiSelectArrayWithCheckbox($htmlname, &$array, $varpage, $pos = '
', $draganddrop = 0)
11130 global $conf, $langs, $user;
11132 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER
')) {
11135 if (empty($array)) {
11139 $tmpvar = "MAIN_SELECTEDFIELDS_" . $varpage; // To get list of saved selected fields to show
11141 if (!empty($user->conf->$tmpvar)) { // A list of fields was already customized for user
11142 $tmparray = explode(',
', $user->conf->$tmpvar);
11143 foreach ($array as $key => $val) {
11145 //var_dump($tmparray);
11146 if (in_array($key, $tmparray)) {
11147 $array[$key]['checked
'] = 1;
11149 $array[$key]['checked
'] = 0;
11152 } else { // There is no list of fields already customized for user
11153 foreach ($array as $key => $val) {
11154 if (!empty($array[$key]['checked
']) && $array[$key]['checked
'] < 0) {
11155 $array[$key]['checked
'] = 0;
11160 $listoffieldsforselection = '';
11161 $listcheckedstring = '';
11163 foreach ($array as $key => $val) {
11165 // var_dump(array_key_exists('enabled
', $val));
11166 // var_dump(!$val['enabled
']);
11167 if (array_key_exists('enabled
', $val) && isset($val['enabled
']) && !$val['enabled
']) {
11168 unset($array[$key]); // We don't want
this field
11171 if (!empty($val[
'type']) && $val[
'type'] ==
'separate') {
11176 if (!empty($val[
'label']) && $val[
'label']) {
11177 if (!empty($val[
'langfile']) && is_object($langs)) {
11178 $langs->load($val[
'langfile']);
11182 $listoffieldsforselection .=
'<li '.(!empty($draganddrop) ?
'class="fieldsortable" id="'.$key :
'').
'"><input type="checkbox" id="checkbox' . $key .
'" value="' . $key .
'"' . ((!array_key_exists(
'checked', $val) || empty($val[
'checked']) || $val[
'checked'] ==
'-1') ?
'' :
' checked="checked"') .
' data-position="'.(empty($val[
'position']) ?
'' : $val[
'position']).
'" />';
11183 $listoffieldsforselection .=
'<label for="checkbox' . $key .
'" class="paddingleft">';
11184 $listoffieldsforselection .= dolPrintHTML(
dol_string_nohtmltag($langs->trans($val[
'label'])));
11185 $listoffieldsforselection .=
'</label>';
11186 if (!empty($draganddrop)) {
11187 $listoffieldsforselection .= img_picto($langs->trans(
"MoveField", !empty($key) ? $key :
'none'),
'grip_title',
'class="opacitymedium boxhandle hideonsmartphone cursormove marginleftonly"');
11189 $listoffieldsforselection .=
'</li>';
11190 $listcheckedstring .= (empty($val[
'checked']) ?
'' : $key .
',');
11194 $out =
'<!-- Component multiSelectArrayWithCheckbox ' . $htmlname .
' -->
11196 <dl class="dropdown">
11198 <a href="#' . $htmlname .
'" class="multiselectpicto">
11199 ' . img_picto(
'',
'list') .
'
11201 <input type="hidden" class="' . $htmlname .
'" name="' . $htmlname .
'" value="' . $listcheckedstring .
'">
11203 <dd class="dropdowndd">
11204 <div class="multiselectcheckbox'.$htmlname.
'">
11205 <ul class="'.$htmlname.(((string) $pos ==
'1' || (
string) $pos ==
'left') ?
'left' :
'').(!empty($draganddrop) ?
' sortable' :
'').
'">
11206 <li class="liinputsearch">
11207 <input class="inputsearch_dropdownselectedfields width90p minwidth200imp" style="width:90%;" type="text" placeholder="'.$langs->trans(
'Search').
'">
11209 '.$listoffieldsforselection.
'
11216 function updateFieldOrder() {
11217 var positionfields = $(".sortable").sortable("toArray");
11219 url: \''.DOL_URL_ROOT.
'/core/ajax/changepositionfields.php?positionfields=\'+positionfields+\'&token='.
newToken().
'&action=listafterchangingpositionfields&contextpage='.$varpage.
'&userid='.$user->id.
'\',
11221 success: function () {
11223 window.location.href = "'.$_SERVER[
"PHP_SELF"].
'";
11227 $( ".sortable" ).sortable({
11228 handle: \'.boxhandle\',
11229 revert: \'invalid\',
11230 items: \'.fieldsortable\',
11231 stop: function(event, ui) {
11232 console.log("We moved box so we call updateBoxOrder with ajax actions");
11233 updateFieldOrder(); /* 1 to avoid message after a move */
11238 <script nonce="' .
getNonce() .
'" type="text/javascript">
11239 jQuery(document).ready(function () {
11240 $(\'.multiselectcheckbox' . $htmlname .
' input[type="checkbox"]\').on("click", function () {
11241 console.log("A new field was added/removed, we edit field input[name=formfilteraction]");
11243 $("input:hidden[name=formfilteraction]").val(\'listafterchangingselectedfields\'); // Update field so we know we changed something on selected fields after POST
11245 var title = $(this).val() + ",";
11246 if ($(this).is(\':checked\')) {
11247 $(\'.' . $htmlname .
'\').val(title + $(\'.' . $htmlname .
'\').val());
11250 $(\'.' . $htmlname .
'\').val( $(\'.' . $htmlname .
'\').val().replace(title, \'\') )
11252 // Now, we submit page
11253 //$(this).parents(\'form:first\').submit();
11256 $("input.inputsearch_dropdownselectedfields").on("keyup", function() {
11257 console.log("keyup on inputsearch_dropdownselectedfields");
11258 var value = $(this).val().toLowerCase();
11259 $(\'.multiselectcheckbox'.$htmlname.
' li > label\').filter(function() {
11260 $(this).parent().toggle($(this).text().toLowerCase().indexOf(value) > -1)
11264 if (empty(
$conf->browser->layout) ||
$conf->browser->layout !=
'phone') {
11266 $(".dropdown dt a").on("click", function () {
11267 console.log("Click on dropdown, we set focus to search field");
11268 setTimeout(() => { $(\'.inputsearch_dropdownselectedfields\').focus(); }, 200);
11292 include_once DOL_DOCUMENT_ROOT .
'/categories/class/categorie.class.php';
11295 $categories = $cat->containing(
$id, $type);
11297 if ($rendermode == 1 || $rendermode == 2) {
11298 $toprint = array();
11299 foreach ($categories as
$c) {
11300 $ways =
$c->print_all_ways(
'auto', ($nolink ?
'none' :
''), 0, 1, ($rendermode == 2 ? 0 : 1));
11301 foreach ($ways as $way) {
11302 $color =
$c->color;
11303 $sfortag =
'<li class="select2-search-choice-dolibarr noborderoncategories'.(empty($toprint) ?
' nomarginleft' :
'');
11304 $forced_color =
'categtextwhite';
11306 $forced_color =
'categtextblack';
11308 $sfortag .=
' '.$forced_color;
11310 $sfortag .= ($color ?
' style="background: #' . $color .
';"' :
' style="background: #bbb"');
11311 $titlestring = $ways[0];
11313 $sfortag .=
' title="' . dolPrintHTMLForAttribute($titlestring) .
'"';
11315 if ($rendermode == 1) {
11316 $sfortag .=
'<a href="'.DOL_URL_ROOT.
'/categories/viewcat.php?id='.((int)
$c->id).
'&type='.urlencode(
$c->type).
'" class="'.$forced_color.
'">';
11317 $sfortag .= img_picto(
'',
'category',
'class="paddingright"');
11318 if (
$conf->dol_optimize_smallscreen) {
11319 $sfortag .= dolPrintHTML(
dol_trunc(
$c->label, 8));
11321 $sfortag .= dolPrintHTML(
$c->label);
11323 $sfortag .=
'</a>';
11327 $sfortag .=
'</li>';
11329 $toprint[] = $sfortag;
11332 if (empty($toprint)) {
11335 return '<div class="select2-container-multi-dolibarr"><ul class="select2-choices-dolibarr">' . implode(
' ', $toprint) .
'</ul></div>';
11339 if ($rendermode == 0) {
11340 $arrayselected = array();
11341 $cate_arbo = $this->select_all_categories($type,
'',
'parent', 64, 0, 3);
11342 foreach ($categories as
$c) {
11343 $arrayselected[(string)
$c->id] = (
string)
$c->id;
11346 return $this->multiselectarray(
'categories', $cate_arbo, $arrayselected, 0, 0,
'', 0,
'100%',
'disabled',
'category');
11349 return 'ErrorBadValueForParameterRenderMode';
11363 global
$conf, $langs, $hookmanager;
11369 $object->fetchObjectLinked();
11372 $hookmanager->initHooks(array(
'commonobject'));
11373 $parameters = array(
11374 'morehtmlright' => $morehtmlright,
11375 'compatibleImportElementsList' => &$compatibleImportElementsList,
11377 $reshook = $hookmanager->executeHooks(
'showLinkedObjectBlock', $parameters,
$object, $action);
11379 $nbofdifferenttypes = count(
$object->linkedObjects);
11381 if (empty($reshook)) {
11382 print
'<!-- showLinkedObjectBlock -->';
11383 print
load_fiche_titre($langs->trans($title), $morehtmlright,
'', 0,
'',
'showlinkedobjectblock');
11386 print
'<div class="div-table-responsive-no-min">';
11387 print
'<table class="noborder allwidth" data-block="showLinkedObject" data-element="' .
$object->element .
'" data-elementid="' .
$object->id .
'" >';
11389 print
'<tr class="liste_titre">';
11390 print
'<td>' . $langs->trans(
"Type") .
'</td>';
11391 print
'<td>' . $langs->trans(
"Ref") .
'</td>';
11394 print
'<td class="right">' . $langs->trans(
"AmountHTShort") .
'</td>';
11395 print
'<td class="right">' . $langs->trans(
"Status") .
'</td>';
11399 $nboftypesoutput = 0;
11401 foreach (
$object->linkedObjects as $objecttype => $objects) {
11402 $tplpath = $element = $subelement = $objecttype;
11405 global $showImportButton;
11406 $showImportButton =
false;
11407 if (!empty($compatibleImportElementsList) && in_array($element, $compatibleImportElementsList)) {
11408 $showImportButton =
true;
11413 if ($objecttype !=
'supplier_proposal' && preg_match(
'/^([^_]+)_([^_]+)/i', $objecttype, $regs)) {
11414 $element = $regs[1];
11415 $subelement = $regs[2];
11416 $tplpath = $element .
'/' . $subelement;
11418 $tplname =
'linkedobjectblock';
11421 if (preg_match(
'/^([^@]+)@([^@]+)$/i', $objecttype, $regs)) {
11422 $element = $regs[1];
11424 $tplpath =
$module.
'/' . $element;
11425 $tplname = $tplname.
'_'.$element;
11429 if ($objecttype ==
'facture') {
11430 $tplpath =
'compta/' . $element;
11434 } elseif ($objecttype ==
'facturerec') {
11435 $tplpath =
'compta/facture';
11436 $tplname =
'linkedobjectblockForRec';
11440 } elseif ($objecttype ==
'propal') {
11441 $tplpath =
'comm/' . $element;
11445 } elseif ($objecttype ==
'supplier_proposal') {
11449 } elseif ($objecttype ==
'shipping' || $objecttype ==
'shipment' || $objecttype ==
'expedition') {
11450 $tplpath =
'expedition';
11454 } elseif ($objecttype ==
'reception') {
11455 $tplpath =
'reception';
11459 } elseif ($objecttype ==
'delivery') {
11460 $tplpath =
'delivery';
11464 } elseif ($objecttype ==
'ficheinter') {
11465 $tplpath =
'fichinter';
11469 } elseif ($objecttype ==
'invoice_supplier') {
11470 $tplpath =
'fourn/facture';
11471 } elseif ($objecttype ==
'order_supplier') {
11472 $tplpath =
'fourn/commande';
11473 } elseif ($objecttype ==
'expensereport') {
11474 $tplpath =
'expensereport';
11475 } elseif ($objecttype ==
'subscription') {
11476 $tplpath =
'adherents';
11477 } elseif ($objecttype ==
'conferenceorbooth') {
11478 $tplpath =
'eventorganization';
11479 } elseif ($objecttype ==
'conferenceorboothattendee') {
11480 $tplpath =
'eventorganization';
11481 } elseif ($objecttype ==
'mo') {
11486 } elseif ($objecttype ==
'project_task') {
11487 $tplpath =
'projet/tasks';
11490 global $linkedObjectBlock;
11491 $linkedObjectBlock = $objects;
11494 $dirtpls = array_merge(
$conf->modules_parts[
'tpl'], array(
'/' . $tplpath .
'/tpl'));
11496 foreach ($dirtpls as $reldir) {
11497 $reldir = rtrim($reldir,
'/');
11498 if ($nboftypesoutput == ($nbofdifferenttypes - 1)) {
11499 global $noMoreLinkedObjectBlockAfter;
11500 $noMoreLinkedObjectBlockAfter = 1;
11502 $file =
dol_buildpath($reldir .
'/' . $tplname .
'.tpl.php');
11503 if (file_exists($file)) {
11504 $res = @include $file;
11506 $nboftypesoutput++;
11513 if (!$nboftypesoutput) {
11514 print
'<tr><td colspan="7"><span class="opacitymedium">' . $langs->trans(
"None") .
'</span></td></tr>';
11519 if (!empty($compatibleImportElementsList)) {
11520 $res = @include
dol_buildpath(
'core/tpl/objectlinked_lineimport.tpl.php');
11526 return $nbofdifferenttypes;
11540 global
$conf, $langs, $hookmanager, $form;
11545 if (empty($form)) {
11546 $form =
new Form($this->db);
11550 $linktoelemlist =
'';
11551 $listofidcompanytoscan =
'';
11553 if (!is_object(
$object->thirdparty)) {
11554 if (
$object->element ==
'subscription' && isset(
$object->fk_adherent)) {
11560 $fk_adherent = $subby->fk_adherent;
11561 $adh->fetch($fk_adherent);
11562 $thirdparty_id = $adh->fetch_thirdparty();
11565 $thirdparty_id =
$object->thirdparty->id;
11568 $possiblelinks = array();
11570 $dontIncludeCompletedItems =
getDolGlobalString(
'DONT_INCLUDE_COMPLETED_ELEMENTS_LINKS');
11572 if (!empty($thirdparty_id) && $thirdparty_id > 0) {
11573 $listofidcompanytoscan = (int) $thirdparty_id;
11575 $listofidcompanytoscan .=
',' . (int)
$object->thirdparty->parent;
11578 include_once DOL_DOCUMENT_ROOT .
'/projet/class/project.class.php';
11579 $tmpproject =
new Project($this->db);
11580 $tmpproject->fetch((
int)
$object->fk_project);
11581 if ($tmpproject->socid > 0 && ($tmpproject->socid != $thirdparty_id)) {
11582 $listofidcompanytoscan .=
',' . (int) $tmpproject->socid;
11584 unset($tmpproject);
11587 $possiblelinks = array(
11591 'label' =>
'LinkToProposal',
11592 'sql' =>
"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM " . $this->db->prefix() .
"societe as s, " . $this->db->prefix() .
"propal as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (" . $this->db->sanitize($listofidcompanytoscan) .
') AND t.entity IN (' .
getEntity(
'propal') .
')'.($dontIncludeCompletedItems ?
' AND t.fk_statut < 4' :
''),
11594 'shipping' => array(
11597 'label' =>
'LinkToExpedition',
11598 'sql' =>
"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref FROM " . $this->db->prefix() .
"societe as s, " . $this->db->prefix() .
"expedition as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (" . $this->db->sanitize($listofidcompanytoscan) .
') AND t.entity IN (' .
getEntity(
'shipping') .
')'.($dontIncludeCompletedItems ?
' AND t.fk_statut < 2' :
''),
11603 'label' =>
'LinkToOrder',
11604 'sql' =>
"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM " . $this->db->prefix() .
"societe as s, " . $this->db->prefix() .
"commande as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (" . $this->db->sanitize($listofidcompanytoscan) .
') AND t.entity IN (' .
getEntity(
'commande') .
')'.($dontIncludeCompletedItems ?
' AND t.facture < 1' :
''),
11605 'linkname' =>
'commande',
11607 'subscription' => array(
11610 'label' =>
'LinkToMemberSubscription',
11611 'sql' =>
"SELECT a.fk_soc as socid, CONCAT(a.firstname, ' ', a.lastname) as name, a.entity as client, sub.rowid, sub.note as ref, '' as ref_client, sub.subscription as total_ht FROM " . $this->db->prefix() .
"adherent as a, " . $this->db->prefix() .
"subscription as sub WHERE sub.fk_adherent = a.rowid AND a.fk_soc IN (" . $this->db->sanitize($listofidcompanytoscan) .
') AND a.entity IN (' .
getEntity(
'subscription') .
')',
11612 'linkname' =>
'subscription',
11614 'conferenceorboothattendee' => array(
11617 'label' =>
'LinkToConferenceOrBoothAttendee',
11618 'sql' =>
"SELECT s.rowid as socid, CONCAT(a.firstname, ' ', a.lastname) as name, a.rowid as rowid, a.fk_project as fk_project, a.ref as ref, a.email as email, a.date_subscription as date_subscription FROM "
11619 .$this->db->prefix().
"societe as s, "
11620 .$this->db->prefix().
"eventorganization_conferenceorboothattendee as a WHERE a.fk_soc = s.rowid AND a.fk_soc IN ("
11621 .$this->db->sanitize($listofidcompanytoscan) .
') AND s.entity IN (' .
getEntity(
'conferenceorboothattendee') .
')'
11622 . (empty(
$object->fk_project) ?
'' :
' AND a.fk_project = ' . (int)
$object->fk_project),
11623 'linkname' =>
'attendee'
11625 'invoice' => array(
11628 'label' =>
'LinkToInvoice',
11629 'sql' =>
"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM " . $this->db->prefix() .
"societe as s, " . $this->db->prefix() .
"facture as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (" . $this->db->sanitize($listofidcompanytoscan) .
') AND t.entity IN (' .
getEntity(
'invoice') .
')'.($dontIncludeCompletedItems ?
' AND t.paye < 1' :
''),
11630 'linkname' =>
'facture',
11632 'invoice_template' => array(
11635 'label' =>
'LinkToTemplateInvoice',
11636 'sql' =>
"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.titre as ref, t.total_ht FROM " . $this->db->prefix() .
"societe as s, " . $this->db->prefix() .
"facture_rec as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (" . $this->db->sanitize($listofidcompanytoscan) .
') AND t.entity IN (' .
getEntity(
'invoice') .
')',
11638 'contrat' => array(
11641 'label' =>
'LinkToContract',
11642 'sql' =>
"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_customer as ref_client, t.ref_supplier, SUM(td.total_ht) as total_ht
11643 FROM " . $this->db->prefix() .
"societe as s, " . $this->db->prefix() .
"contrat as t, " . $this->db->prefix() .
"contratdet as td WHERE t.fk_soc = s.rowid AND td.fk_contrat = t.rowid AND t.fk_soc IN (" . $this->db->sanitize($listofidcompanytoscan) .
') AND t.entity IN (' .
getEntity(
'contract') .
') GROUP BY s.rowid, s.nom, s.client, t.rowid, t.ref, t.ref_customer, t.ref_supplier',
11645 'fichinter' => array(
11648 'label' =>
'LinkToIntervention',
11649 'sql' =>
"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref FROM " . $this->db->prefix() .
"societe as s, " . $this->db->prefix() .
"fichinter as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (" . $this->db->sanitize($listofidcompanytoscan) .
') AND t.entity IN (' .
getEntity(
'intervention') .
')',
11651 'supplier_proposal' => array(
11654 'label' =>
'LinkToSupplierProposal',
11655 'sql' =>
"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, '' as ref_supplier, t.total_ht FROM " . $this->db->prefix() .
"societe as s, " . $this->db->prefix() .
"supplier_proposal as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (" . $this->db->sanitize($listofidcompanytoscan) .
') AND t.entity IN (' .
getEntity(
'supplier_proposal') .
')'.($dontIncludeCompletedItems ?
' AND t.fk_statut < 4' :
''),
11657 'order_supplier' => array(
11660 'label' =>
'LinkToSupplierOrder',
11661 'sql' =>
"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM " . $this->db->prefix() .
"societe as s, " . $this->db->prefix() .
"commande_fournisseur as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (" . $this->db->sanitize($listofidcompanytoscan) .
') AND t.entity IN (' .
getEntity(
'commande_fournisseur') .
')'.($dontIncludeCompletedItems ?
' AND t.billed < 1' :
''),
11663 'invoice_supplier' => array(
11665 'perms' => 1,
'label' =>
'LinkToSupplierInvoice',
11666 'sql' =>
"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM " . $this->db->prefix() .
"societe as s, " . $this->db->prefix() .
"facture_fourn as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (" . $this->db->sanitize($listofidcompanytoscan) .
') AND t.entity IN (' .
getEntity(
'facture_fourn') .
')'.($dontIncludeCompletedItems ?
' AND t.paye < 1' :
''),
11671 'label' =>
'LinkToTicket',
11672 'sql' =>
"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.track_id, '0' as total_ht FROM " . $this->db->prefix() .
"societe as s, " . $this->db->prefix() .
"ticket as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (" . $this->db->sanitize($listofidcompanytoscan) .
') AND t.entity IN (' .
getEntity(
'ticket') .
')'.($dontIncludeCompletedItems ?
' AND t.fk_statut < 8' :
''),
11677 'label' =>
'LinkToMo',
11678 'sql' =>
"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.rowid, '0' as total_ht FROM " . $this->db->prefix() .
"societe as s INNER JOIN " . $this->db->prefix() .
"mrp_mo as t ON t.fk_soc = s.rowid WHERE t.fk_soc IN (" . $this->db->sanitize($listofidcompanytoscan) .
') AND t.entity IN (' .
getEntity(
'mo') .
')'.($dontIncludeCompletedItems ?
' AND t.status < 3' :
''),
11683 if (
$object->table_element ==
'commande_fournisseur') {
11684 $possiblelinks[
'mo'][
'sql'] =
"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.rowid, '0' as total_ht FROM ".$this->db->prefix().
"societe as s INNER JOIN ".$this->db->prefix().
'mrp_mo as t ON t.fk_soc = s.rowid WHERE t.entity IN ('.
getEntity(
'mo').
')'.($dontIncludeCompletedItems ?
' AND t.status < 3' :
'');
11685 } elseif (
$object->table_element ==
'mrp_mo') {
11686 $possiblelinks[
'order_supplier'][
'sql'] =
"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".$this->db->prefix().
"societe as s, ".$this->db->prefix().
'commande_fournisseur as t WHERE t.fk_soc = s.rowid AND t.entity IN ('.
getEntity(
'commande_fournisseur').
')'.($dontIncludeCompletedItems ?
' AND t.billed < 1' :
'');
11690 if (!empty($listofidcompanytoscan)) {
11692 $hookmanager->initHooks(array(
'commonobject'));
11693 $parameters = array(
'listofidcompanytoscan' => $listofidcompanytoscan,
'possiblelinks' => $possiblelinks);
11694 $reshook = $hookmanager->executeHooks(
'showLinkToObjectBlock', $parameters,
$object, $action);
11697 if (empty($reshook)) {
11698 if (is_array($hookmanager->resArray) && count($hookmanager->resArray)) {
11699 $possiblelinks = array_merge($possiblelinks, $hookmanager->resArray);
11701 } elseif ($reshook > 0) {
11702 if (is_array($hookmanager->resArray) && count($hookmanager->resArray)) {
11703 $possiblelinks = $hookmanager->resArray;
11707 if (!empty($possiblelinks)) {
11708 $object->fetchObjectLinked();
11712 $htmltoenteralink =
'';
11713 foreach ($possiblelinks as $key => $possiblelink) {
11715 if (empty($possiblelink[
'enabled'])) {
11722 if (preg_match(
'/^([^@]+)@([^@]+)$/i', $key, $regs)) {
11727 if (!empty($possiblelink[
'perms']) && (empty($restrictlinksto) || in_array($key, $restrictlinksto)) && (empty($excludelinksto) || !in_array($key, $excludelinksto))) {
11728 $htmltoenteralink .=
'<div id="' . $key .
'list"' . (empty(
$conf->use_javascript_ajax) ?
'' :
' style="display:none"') .
'>';
11732 $htmltoenteralink .=
'<br>'.
"\n";
11733 $htmltoenteralink .=
'<!-- form to add a link from anywhere -->'.
"\n";
11734 $htmltoenteralink .=
'<form action="' . $_SERVER[
"PHP_SELF"] .
'" method="POST" name="formlinkedbyref' . $key .
'">';
11735 $htmltoenteralink .=
'<input type="hidden" name="token" value="' .
newToken() .
'">';
11736 $htmltoenteralink .=
'<input type="hidden" name="action" value="addlinkbyref">';
11737 $htmltoenteralink .=
'<input type="hidden" name="id" value="' .
$object->id .
'">';
11738 $htmltoenteralink .=
'<input type="hidden" name="addlink" value="' . $key .(!empty(
$module) ?
'@'.$module :
'').
'">';
11739 $htmltoenteralink .=
'<table class="noborder">';
11740 $htmltoenteralink .=
'<tr class="liste_titre">';
11742 $htmltoenteralink .=
'<td class="center"><input type="text" placeholder="'.dol_escape_htmltag($langs->trans(
"Ref")).
'" name="reftolinkto" value="' .
dol_escape_htmltag(
GETPOST(
'reftolinkto',
'alpha')) .
'">';
11743 $htmltoenteralink .=
'<br>';
11744 $htmltoenteralink .=
'<input type="submit" class="button smallpaddingimp valignmiddle" value="' . $langs->trans(
'ToLink') .
'"> ';
11745 $htmltoenteralink .=
'<input type="submit" class="button smallpaddingimp" name="cancel" value="' . $langs->trans(
'Cancel') .
'">';
11746 $htmltoenteralink .=
'</td>';
11747 $htmltoenteralink .=
'</tr>';
11748 $htmltoenteralink .=
'</table>';
11749 $htmltoenteralink .=
'</form>';
11752 $sql = $possiblelink[
'sql'];
11754 $resqllist = $this->db->query($sql);
11756 $num = $this->db->num_rows($resqllist);
11761 $htmltoenteralink .=
'<br>';
11763 $htmltoenteralink .=
'<!-- form to add a link from object to same thirdparty -->'.
"\n";
11764 $htmltoenteralink .=
'<form action="' . $_SERVER[
"PHP_SELF"] .
'" method="POST" name="formlinked' . $key .
'">';
11765 $htmltoenteralink .=
'<input type="hidden" name="token" value="' .
newToken() .
'">';
11766 $htmltoenteralink .=
'<input type="hidden" name="action" value="addlink">';
11767 $htmltoenteralink .=
'<input type="hidden" name="id" value="' .
$object->id .
'">';
11768 $htmltoenteralink .=
'<input type="hidden" name="addlink" value="' . $key . (!empty(
$module) ?
'@'.$module :
'').
'">';
11769 $htmltoenteralink .=
'<table class="noborder">';
11772 case 'conferenceorboothattendee':
11774 $htmltoenteralink .= $this->makeAddLinkToAttendee(
$object, $key, $possiblelink, $num, $resqllist);
11779 $htmltoenteralink .= $this->makeAddLinkToObject(
$object, $key, $possiblelink, $num, $resqllist);
11783 $htmltoenteralink .=
'</table>';
11784 $htmltoenteralink .=
'<div class="center">';
11786 $htmltoenteralink .=
'<input type="submit" class="button valignmiddle marginleftonly marginrightonly smallpaddingimp" value="' . $langs->trans(
'ToLink') .
'">';
11788 if (empty(
$conf->use_javascript_ajax)) {
11789 $htmltoenteralink .=
'<input type="submit" class="button button-cancel marginleftonly marginrightonly smallpaddingimp" name="cancel" value="' . $langs->trans(
"Cancel") .
'"></div>';
11791 $htmltoenteralink .=
'<input type="submit" onclick="jQuery(\'#' . $key .
'list\').toggle(); return false;" class="button button-cancel marginleftonly marginrightonly smallpaddingimp" name="cancel" value="' . $langs->trans(
"Cancel") .
'"></div>';
11793 $htmltoenteralink .=
'</form>';
11796 $this->db->free($resqllist);
11798 dol_print_error($this->db);
11800 $htmltoenteralink .=
'</div>';
11805 $linktoelemlist .=
'<li><a href="#linkto' . $key .
'" class="linkto dropdowncloseonclick" rel="' . $key .
'">' . $langs->trans($possiblelink[
'label']) .
' (' . $num .
')</a></li>';
11808 $linktoelemlist .=
'<li><span class="linktodisabled">' . $langs->trans($possiblelink[
'label']) .
' (0)</span></li>';
11813 if ($linktoelemlist) {
11815 <dl class="dropdown" id="linktoobjectname">
11817 if (!empty(
$conf->use_javascript_ajax)) {
11818 $linktoelem .=
'<dt><a href="#linktoobjectname"><span class="fas fa-link paddingrightonly"></span>' . $langs->trans(
"LinkTo") .
'...</a></dt>';
11820 $linktoelem .=
'<dd>
11821 <div class="multiselectlinkto">
11822 <ul class="ulselectedfields">' . $linktoelemlist .
'
11831 if (!empty(
$conf->use_javascript_ajax)) {
11832 print
'<!-- Add js to show linkto box -->
11833 <script nonce="' .
getNonce() .
'">
11834 jQuery(document).ready(function() {
11835 jQuery(".linkto").click(function() {
11836 console.log("We choose to show/hide links for rel="+jQuery(this).attr(\'rel\')+" so #"+jQuery(this).attr(\'rel\')+"list");
11837 jQuery("#"+jQuery(this).attr(\'rel\')+"list").toggle();
11845 return array(
'linktoelem' => $linktoelem,
'htmltoenteralink' => $htmltoenteralink);
11847 print $htmltoenteralink;
11850 return $linktoelem;
11867 public function selectyesno($htmlname, $value =
'', $option = 0, $disabled =
false, $useempty = 0, $addjscombo = 0, $morecss =
'yesno width75', $labelyes =
'Yes', $labelno =
'No')
11878 $disabled = ($disabled ?
' disabled' :
'');
11880 $resultyesno =
'<select class="flat' . ($morecss ?
' ' . $morecss :
'') .
'" id="' . $htmlname .
'" name="' . $htmlname .
'"' . $disabled .
'>' .
"\n";
11882 $resultyesno .=
'<option value="-1"' . (($value < 0) ?
' selected' :
'') .
'> </option>' .
"\n";
11884 if ((
"$value" ==
'yes') || ($value == 1)) {
11885 $resultyesno .=
'<option value="' . $yes .
'" selected>' . $langs->trans($labelyes) .
'</option>' .
"\n";
11886 $resultyesno .=
'<option value="' . $no .
'">' . $langs->trans($labelno) .
'</option>' .
"\n";
11888 $selected = (($useempty && $value !=
'0' && $value !=
'no') ?
'' :
' selected');
11889 $resultyesno .=
'<option value="' . $yes .
'">' . $langs->trans($labelyes) .
'</option>' .
"\n";
11890 $resultyesno .=
'<option value="' . $no .
'"' . $selected .
'>' . $langs->trans($labelno) .
'</option>' .
"\n";
11892 $resultyesno .=
'</select>' .
"\n";
11895 $resultyesno .=
ajax_combobox($htmlname, array(), 0, 0,
'resolve', ($useempty < 0 ? (
string) $useempty :
'-1'), $morecss);
11898 return $resultyesno;
11915 $sql =
"SELECT rowid, label";
11916 $sql .=
" FROM " . $this->db->prefix() .
"export_model";
11917 $sql .=
" WHERE type = '" . $this->db->escape($type) .
"'";
11918 $sql .=
" ORDER BY rowid";
11919 $result = $this->db->query($sql);
11921 print
'<select class="flat" id="select_' . $htmlname .
'" name="' . $htmlname .
'">';
11923 print
'<option value="-1"> </option>';
11926 $num = $this->db->num_rows($result);
11928 while ($i < $num) {
11929 $obj = $this->db->fetch_object($result);
11930 if ($selected == $obj->rowid) {
11931 print
'<option value="' . $obj->rowid .
'" selected>';
11933 print
'<option value="' . $obj->rowid .
'">';
11941 dol_print_error($this->db);
11963 public function showrefnav(
$object, $paramid, $morehtml =
'', $shownav = 1, $fieldid =
'rowid', $fieldref =
'ref', $morehtmlref =
'', $moreparam =
'', $nodbprefix = 0, $morehtmlleft =
'', $morehtmlstatus =
'', $morehtmlright =
'')
11965 global
$conf, $langs, $hookmanager, $extralanguages;
11968 if (empty($fieldid)) {
11969 $fieldid =
'rowid';
11971 if (empty($fieldref)) {
11976 $addgendertxt =
'';
11977 if (property_exists(
$object,
'gender') && !empty(
$object->gender)) {
11978 $addgendertxt =
' ';
11981 $addgendertxt .=
'<i class="fas fa-mars valignmiddle"></i>';
11984 $addgendertxt .=
'<i class="fas fa-venus valignmiddle"></i>';
11987 $addgendertxt .=
'<i class="fas fa-transgender valignmiddle"></i>';
11993 if (is_object($hookmanager)) {
11994 $parameters = array(
'showrefnav' =>
true);
11995 $reshook = $hookmanager->executeHooks(
'printFieldListWhere', $parameters,
$object);
11996 if (!empty($hookmanager->resPrint)) {
11997 if (empty(
$object->next_prev_filter) && preg_match(
'/^\s*AND/i', $hookmanager->resPrint)) {
11998 $object->next_prev_filter = (string) preg_replace(
'/^\s*AND\s*/i',
'', $hookmanager->resPrint);
11999 } elseif (!empty(
$object->next_prev_filter) && !preg_match(
'/^\s*AND/i', $hookmanager->resPrint)) {
12000 $object->next_prev_filter .=
' AND '.$hookmanager->resPrint;
12002 $object->next_prev_filter .= $hookmanager->resPrint;
12007 $previous_ref = $next_ref =
'';
12010 $object->load_previous_next_ref((isset(
$object->next_prev_filter) ?
$object->next_prev_filter :
''), $fieldid, $nodbprefix);
12012 $navurl = $_SERVER[
"PHP_SELF"];
12015 if ($paramid ==
'api_token_card') {
12016 if (preg_match(
'/\/user\/api_token/', $navurl)) {
12017 $navurl = preg_replace(
'/card/',
'list', $navurl);
12023 if ($paramid ==
'project_ref') {
12024 if (preg_match(
'/\/tasks\/(task|contact|note|document)\.php/', $navurl)) {
12025 $navurl = preg_replace(
'/\/tasks\/(task|contact|time|note|document)\.php/',
'/tasks.php', $navurl);
12030 $previous_ref =
$object->ref_previous ?
'<a accesskey="p" alt="'.dol_escape_htmltag($langs->trans(
"Previous")).
'" title="' .
$conf->browser->stringforfirstkey .
' p" class="classfortooltip reposition" href="' . $navurl .
'?' . $paramid .
'=' . urlencode(
$object->ref_previous) . $moreparam .
'"><i class="fa fa-chevron-left"></i></a>' :
'<span class="inactive"><i class="fa fa-chevron-left opacitymedium"></i></span>';
12031 $next_ref =
$object->ref_next ?
'<a accesskey="n" alt="'.dol_escape_htmltag($langs->trans(
"Next")).
'" title="' .
$conf->browser->stringforfirstkey .
' n" class="classfortooltip reposition" href="' . $navurl .
'?' . $paramid .
'=' . urlencode(
$object->ref_next) . $moreparam .
'"><i class="fa fa-chevron-right"></i></a>' :
'<span class="inactive"><i class="fa fa-chevron-right opacitymedium"></i></span>';
12035 $ret .=
'<!-- Start banner content --><div style="vertical-align: middle">';
12038 if ($morehtmlright) {
12039 $ret .=
'<div class="inline-block floatleft">' . $morehtmlright .
'</div>';
12042 if ($previous_ref || $next_ref || $morehtml) {
12043 $ret .=
'<div class="pagination paginationref"><ul class="right">';
12045 if ($morehtml &&
getDolGlobalInt(
'MAIN_OPTIMIZEFORTEXTBROWSER') < 2) {
12046 $ret .=
'<!-- morehtml --><li class="noborder litext' . (($shownav && $previous_ref && $next_ref) ?
' clearbothonsmartphone' :
'') .
'">' . $morehtml .
'</li>';
12048 if ($shownav && ($previous_ref || $next_ref)) {
12049 $ret .=
'<li class="pagination">' . $previous_ref .
'</li>';
12050 $ret .=
'<li class="pagination">' . $next_ref .
'</li>';
12052 if ($previous_ref || $next_ref || $morehtml) {
12053 $ret .=
'</ul></div>';
12057 $parameters = array(
'morehtmlstatus' => $morehtmlstatus);
12058 $reshook = $hookmanager->executeHooks(
'moreHtmlStatus', $parameters,
$object);
12059 if (empty($reshook)) {
12060 $morehtmlstatus .= $hookmanager->resPrint;
12062 $morehtmlstatus = $hookmanager->resPrint;
12064 if ($morehtmlstatus) {
12065 $ret .=
'<!-- status --><div class="statusref">' . $morehtmlstatus .
'</div>';
12068 $parameters = array();
12069 $reshook = $hookmanager->executeHooks(
'moreHtmlRef', $parameters,
$object);
12070 if (empty($reshook)) {
12071 $morehtmlref .= $hookmanager->resPrint;
12072 } elseif ($reshook > 0) {
12073 $morehtmlref = $hookmanager->resPrint;
12077 if ($morehtmlleft) {
12078 if (
$conf->browser->layout ==
'phone') {
12079 $ret .=
'<!-- morehtmlleft --><div class="floatleft">' . $morehtmlleft .
'</div>';
12081 $ret .=
'<!-- morehtmlleft --><div class="inline-block floatleft">' . $morehtmlleft .
'</div>';
12086 $ret .=
'<!-- Ref or ID --><div class="inline-block floatleft valignmiddle maxwidth750 marginbottomonly refid' . (($shownav && ($previous_ref || $next_ref)) ?
' refidpadding' :
'') .
'">';
12089 if (
$object->element ==
'societe') {
12090 $ret .=
'<span class="valignmiddle">'.dolPrintHTML((
string)
$object->name).
'</span>';
12093 $arrayoflangcode = array();
12098 if (is_array($arrayoflangcode) && count($arrayoflangcode)) {
12099 if (!is_object($extralanguages)) {
12100 include_once DOL_DOCUMENT_ROOT .
'/core/class/extralanguages.class.php';
12103 $extralanguages->fetch_name_extralanguages(
'societe');
12107 if (!empty($extralanguages->attributes[
'societe']) && !empty($extralanguages->attributes[
'societe'][
'name'])) {
12108 $object->fetchValuesForExtraLanguages();
12112 foreach ($arrayoflangcode as $extralangcode) {
12114 if (
$object->array_languages[
'name'][$extralangcode]) {
12115 $htmltext .=
$object->array_languages[
'name'][$extralangcode];
12117 $htmltext .=
'<span class="opacitymedium">' . $langs->trans(
"SwitchInEditModeToAddTranslation") .
'</span>';
12120 $ret .=
'<!-- Show translations of name -->' .
"\n";
12121 $ret .= $this->textwithpicto(
'', $htmltext, -1,
'language',
'opacitymedium paddingleft');
12124 } elseif (
$object->element ==
'member') {
12125 '@phan-var-force Adherent $object';
12126 $ret .=
$object->ref .
'<br>';
12127 $fullname =
$object->getFullName($langs);
12129 $ret .=
'<span class="valignmiddle">'.dolPrintHTML((
string)
$object->societe) . ((!empty($fullname) &&
$object->societe != $fullname) ?
' (' .
dol_htmlentities($fullname) . $addgendertxt .
')' :
'').
'</span>';
12131 $ret .=
'<span class="valignmiddle">'.dolPrintHTML($fullname) . $addgendertxt . ((!empty(
$object->societe) &&
$object->societe != $fullname) ?
' (' .
dol_htmlentities((
string)
$object->societe) .
')' :
'').
'</span>';
12133 } elseif (in_array(
$object->element, array(
'contact',
'user'))) {
12134 $ret .=
'<span class="valignmiddle">'.dolPrintHTML(
$object->getFullName($langs)).
'</span>'.$addgendertxt;
12135 } elseif (
$object->element ==
'usergroup') {
12137 } elseif (in_array(
$object->element, array(
'action',
'agenda'))) {
12138 '@phan-var-force ActionComm $object';
12140 } elseif (in_array(
$object->element, array(
'adherent_type'))) {
12142 } elseif (
$object->element ==
'ecm_directories') {
12144 } elseif (
$object->element ==
'accountingbookkeeping' && !empty(
$object->context[
'mode']) &&
$object->context[
'mode'] ==
'_tmp') {
12145 $ret .=
'<span class="valignmiddle">'.$langs->trans(
"Draft").
'</span>';
12147 '@phan-var-force Ticket $object';
12148 $ret .=
'<span class="valignmiddle">'.dolPrintHTML(!empty(
$object->$fieldref) ?
$object->$fieldref :
"").
'</span>';
12149 $ret .=
' <span class="nobold small" title="'.dolPrintHTMLForAttribute($langs->trans(
"TicketTrackId")).
'">('.
$object->track_id.
')</span>';
12150 } elseif ($fieldref !=
'none') {
12152 $ret .=
'<span class="valignmiddle">'.dolPrintHTML(!empty(
$object->$fieldref) ?
$object->$fieldref :
"").
'</span>';
12154 if ($morehtmlref) {
12156 if (substr($morehtmlref, 0, 4) !=
'<div') {
12160 $ret .=
'<!-- morehtmlref -->'.$morehtmlref;
12165 $ret .=
'</div><!-- End banner content -->';
12182 if (empty(
$object->barcode)) {
12187 if (empty(
$object->barcode_type_code) || empty(
$object->barcode_type_coder)) {
12189 $result =
$object->fetchBarCode();
12192 return '<!-- ErrorFetchBarcode -->';
12197 $url = DOL_URL_ROOT .
'/viewimage.php?modulepart=barcode&generator=' . urlencode(
$object->barcode_type_coder) .
'&code=' . urlencode(
$object->barcode) .
'&encoding=' . urlencode(
$object->barcode_type_code);
12198 $out =
'<!-- url barcode = ' . $url .
' -->';
12199 $out .=
'<img src="' . $url .
'"' . ($morecss ?
' class="' . $morecss .
'"' :
'') .
'>';
12222 public static function showphoto($modulepart,
$object, $width = 100, $height = 0, $caneditfield = 0, $cssclass =
'photowithmargin', $imagesize =
'', $addlinktofullsize = 1, $cache = 0, $forcecapture =
'', $noexternsourceoverwrite = 0, $usesharelinkifavailable = 0)
12224 global
$conf, $db, $langs;
12231 $originalfile =
'';
12235 if ($modulepart ==
'societe') {
12236 $dir =
$conf->societe->multidir_output[$entity];
12239 if ((
string) $imagesize ==
'mini') {
12241 } elseif ((
string) $imagesize ==
'small') {
12250 } elseif ($modulepart ==
'contact') {
12251 $dir =
$conf->societe->multidir_output[$entity] .
'/contact';
12253 if (!empty($photo)) {
12255 if ((
string) $imagesize ==
'mini') {
12257 } elseif ((
string) $imagesize ==
'small') {
12262 $originalfile =
get_exdir(0, 0, 0, 0,
$object,
'contact') .
'photos/' . $photo;
12267 } elseif ($modulepart ==
'userphoto') {
12268 $dir =
$conf->user->dir_output;
12270 if (!empty($photo)) {
12272 if ((
string) $imagesize ==
'mini') {
12274 } elseif ((
string) $imagesize ==
'small') {
12279 $originalfile =
get_exdir(0, 0, 0, 0,
$object,
'user') .
'photos/' . $photo;
12283 $altfile =
$object->id .
".jpg";
12287 } elseif ($modulepart ==
'memberphoto') {
12288 $dir =
$conf->member->dir_output;
12290 if (!empty($photo)) {
12292 if ((
string) $imagesize ==
'mini') {
12294 } elseif ((
string) $imagesize ==
'small') {
12299 $originalfile =
get_exdir(0, 0, 0, 0,
$object,
'member') .
'photos/' . $photo;
12303 $altfile =
$object->id .
".jpg";
12310 if ($modulepart !=
"unknown" && method_exists(
$object,
'getDataToShowPhoto')) {
12311 $tmpdata =
$object->getDataToShowPhoto($modulepart, $imagesize);
12313 $dir = $tmpdata[
'dir'];
12314 $file = $tmpdata[
'file'];
12315 $originalfile = $tmpdata[
'originalfile'];
12316 $altfile = $tmpdata[
'altfile'];
12317 $email = $tmpdata[
'email'];
12318 $capture = $tmpdata[
'capture'];
12322 if ($forcecapture) {
12323 $capture = $forcecapture;
12329 if ($file && file_exists($dir .
"/" . $file)) {
12330 if ($addlinktofullsize) {
12332 if ($urladvanced) {
12333 $ret .=
'<a href="' . $urladvanced .
'">';
12335 $ret .=
'<a href="' . DOL_URL_ROOT .
'/viewimage.php?modulepart=' . $modulepart .
'&entity=' . $entity .
'&file=' . urlencode($originalfile) .
'&cache=' . $cache .
'">';
12340 if ($usesharelinkifavailable) {
12342 $relativefileforecm = preg_replace(
'/^'.preg_quote(DOL_DATA_ROOT.
'/',
'/').
'/',
'', $dir.
'/'.$originalfile);
12344 require_once DOL_DOCUMENT_ROOT .
'/ecm/class/ecmfiles.class.php';
12346 $ecmfiles->fetch(0,
'', $relativefileforecm);
12348 $sharekey = (string) $ecmfiles->share;
12351 if (!empty($sharekey)) {
12352 $ret .=
'<img alt="" class="photo' . $modulepart . ($cssclass ?
' ' . $cssclass :
'') .
' photologo' . (preg_replace(
'/[^a-z]/i',
'_', $file)) .
'" ' . ($width ?
' width="' . $width .
'"' :
'') . ($height ?
' height="' . $height .
'"' :
'') .
' src="' . DOL_URL_ROOT .
'/viewimage.php?hashp=' . urlencode($sharekey) .
'&cache=' . urlencode((
string) $cache) .
'">';
12354 $ret .=
'<img alt="" class="photo' . $modulepart . ($cssclass ?
' ' . $cssclass :
'') .
' photologo' . (preg_replace(
'/[^a-z]/i',
'_', $file)) .
'" ' . ($width ?
' width="' . $width .
'"' :
'') . ($height ?
' height="' . $height .
'"' :
'') .
' src="' . DOL_URL_ROOT .
'/viewimage.php?modulepart=' . urlencode($modulepart) .
'&entity=' . ((int) $entity) .
'&file=' . urlencode($file) .
'&cache=' . urlencode((
string) $cache) .
'">';
12356 if ($addlinktofullsize) {
12359 } elseif ($altfile && file_exists($dir .
"/" . $altfile)) {
12360 if ($addlinktofullsize) {
12362 if ($urladvanced) {
12363 $ret .=
'<a href="' . $urladvanced .
'">';
12365 $ret .=
'<a href="' . DOL_URL_ROOT .
'/viewimage.php?modulepart=' . $modulepart .
'&entity=' . $entity .
'&file=' . urlencode($originalfile) .
'&cache=' . $cache .
'">';
12368 $ret .=
'<img class="photo' . $modulepart . ($cssclass ?
' ' . $cssclass :
'') .
'" alt="Photo alt" id="photologo' . (preg_replace(
'/[^a-z]/i',
'_', $file)) .
'" class="' . $cssclass .
'" ' . ($width ?
' width="' . $width .
'"' :
'') . ($height ?
' height="' . $height .
'"' :
'') .
' src="' . DOL_URL_ROOT .
'/viewimage.php?modulepart=' . urlencode($modulepart) .
'&entity=' . ((int) $entity) .
'&file=' . urlencode($altfile) .
'&cache=' . urlencode((
string) $cache) .
'">';
12369 if ($addlinktofullsize) {
12373 $nophoto =
'/public/theme/common/nophoto.png';
12374 $defaultimg =
'identicon';
12375 if (in_array($modulepart, array(
'societe',
'userphoto',
'contact',
'memberphoto'))) {
12376 if ($modulepart ==
'societe' || ($modulepart ==
'memberphoto' && !empty(
$object->morphy) && strpos(
$object->morphy,
'mor') !==
false)) {
12377 $nophoto =
'company';
12379 $nophoto =
'/public/theme/common/user_anonymous.png';
12381 $nophoto =
'/public/theme/common/user_man.png';
12384 $nophoto =
'/public/theme/common/user_woman.png';
12389 if (
isModEnabled(
'gravatar') && $email && empty($noexternsourceoverwrite)) {
12391 $ret .=
'<!-- Put link to gravatar -->';
12392 $ret .=
'<img class="gravatar photo' . $modulepart . ($cssclass ?
' ' . $cssclass :
'') .
'" alt="" title="'.dolPrintHTMLForAttribute(
'Gravatar avatar - '.$email).
'" ' . ($width ?
' width="' . $width .
'"' :
'') . ($height ?
' height="' . $height .
'"' :
'') .
' src="https://www.gravatar.com/avatar/' .
dol_hash(strtolower(trim($email)),
'sha256', 1) .
'?s=' . $width .
'&d=' . $defaultimg .
'">';
12394 if ($nophoto ==
'company') {
12395 $ret .=
'<div class="divforspanimg valignmiddle inline-block center photo' . $modulepart . ($cssclass ?
' ' . $cssclass :
'') .
'" alt="" ' . ($width ?
' width="' . $width .
'"' :
'') . ($height ?
' height="' . $height .
'"' :
'') .
'>' . img_picto(
'',
'company') .
'</div>';
12398 $ret .=
'<img class="photo' . $modulepart . ($cssclass ?
' ' . $cssclass :
'') .
'" alt="" ' . ($width ?
' width="' . $width .
'"' :
'') . ($height ?
' height="' . $height .
'"' :
'') .
' src="' . DOL_URL_ROOT . $nophoto .
'">';
12403 if ($caneditfield) {
12407 $ret .=
'<table class="nobordernopadding centpercent">';
12409 $ret .=
'<tr><td><input type="checkbox" class="flat photodelete" name="deletephoto" id="photodelete"> <label for="photodelete">' . $langs->trans(
"Delete") .
'</label><br><br></td></tr>';
12411 $ret .=
'<tr><td class="tdoverflow">';
12413 $maxmin = $maxfilesizearray[
'maxmin'];
12415 $ret .=
'<input type="hidden" name="MAX_FILE_SIZE" value="' . ($maxmin * 1024) .
'">';
12417 $ret .=
'<input type="file" class="flat maxwidth200onsmartphone" name="photo" id="photoinput" accept="image/*"' . ($capture ?
' capture="' . dolPrintHTMLForAttribute($capture) .
'"' :
'') .
'>';
12418 $ret .=
'</td></tr>';
12419 $ret .=
'</table>';
12444 public function select_dolgroups($selected = 0, $htmlname =
'groupid', $show_empty = 0, $exclude =
'', $disabled = 0, $include =
'', $enableonly = array(), $force_entity =
'0', $multiple =
false, $morecss =
'minwidth200')
12447 global
$conf, $user, $langs;
12450 $excludeGroups =
null;
12451 if (is_array($exclude)) {
12452 $excludeGroups = implode(
",", $exclude);
12455 $includeGroups =
null;
12456 if (is_array($include)) {
12457 $includeGroups = implode(
",", $include);
12460 if (!is_array($selected)) {
12461 $selected = array($selected);
12467 $sql =
"SELECT ug.rowid, ug.nom as name";
12468 if (
isModEnabled(
'multicompany') &&
$conf->entity == 1 && $user->admin && !$user->entity) {
12469 $sql .=
", e.label";
12471 $sql .=
" FROM " . $this->db->prefix() .
"usergroup as ug ";
12472 if (
isModEnabled(
'multicompany') &&
$conf->entity == 1 && $user->admin && !$user->entity) {
12473 $sql .=
" LEFT JOIN " . $this->db->prefix() .
"entity as e ON e.rowid=ug.entity";
12474 if ($force_entity) {
12475 $sql .=
" WHERE ug.entity IN (0, " . ((int) $force_entity) .
")";
12477 $sql .=
" WHERE ug.entity IS NOT NULL";
12480 $sql .=
" WHERE ug.entity IN (0, " . ((int)
$conf->entity) .
")";
12482 if (is_array($exclude) && $excludeGroups) {
12483 $sql .=
" AND ug.rowid NOT IN (" . $this->db->sanitize($excludeGroups) .
")";
12485 if (is_array($include) && $includeGroups) {
12486 $sql .=
" AND ug.rowid IN (" . $this->db->sanitize($includeGroups) .
")";
12488 $sql .=
" ORDER BY ug.nom ASC";
12490 dol_syslog(get_class($this) .
"::select_dolgroups", LOG_DEBUG);
12491 $resql = $this->db->query($sql);
12494 include_once DOL_DOCUMENT_ROOT .
'/core/lib/ajax.lib.php';
12496 $out .=
'<select class="flat' . ($morecss ?
' ' . $morecss :
'') .
'" id="' . $htmlname .
'" name="' . $htmlname . ($multiple ?
'[]' :
'') .
'" ' . ($multiple ?
'multiple' :
'') .
' ' . ($disabled ?
' disabled' :
'') .
'>';
12498 $num = $this->db->num_rows($resql);
12501 if ($show_empty && !$multiple) {
12502 $textforempty =
' ';
12503 if (!is_numeric($show_empty)) {
12506 $out .=
'<option value="-1"' . (in_array(-1, $selected) ?
' selected' :
'') .
'>' . $textforempty .
'</option>' .
"\n";
12509 while ($i < $num) {
12510 $obj = $this->db->fetch_object($resql);
12512 if (is_array($enableonly) && count($enableonly) && !in_array($obj->rowid, $enableonly)) {
12516 $label = $obj->name;
12517 $labelhtml = $obj->name;
12519 $label .=
" (" . $obj->label .
")";
12520 $labelhtml .=
' <span class="opacitymedium">(' . $obj->label .
')</span>';
12523 $out .=
'<option value="' . $obj->rowid .
'"';
12524 if ($disableline) {
12525 $out .=
' disabled';
12527 if ((isset($selected[0]) && is_object($selected[0]) && $selected[0]->
id == $obj->rowid)
12528 || ((!isset($selected[0]) || !is_object($selected[0])) && !empty($selected) && in_array($obj->rowid, $selected))) {
12529 $out .=
' selected';
12531 $out .=
' data-html="'.dol_escape_htmltag($labelhtml).
'"';
12534 $out .=
'</option>';
12539 $out .=
'<option value="-1"' . (in_array(-1, $selected) ?
' selected' :
'') .
'></option>' .
"\n";
12541 $out .=
'<option value="" disabled>' . $langs->trans(
"NoUserGroupDefined") .
'</option>';
12543 $out .=
'</select>';
12547 dol_print_error($this->db);
12562 $out =
'<div class="nowraponall">';
12563 $out .=
'<button type="submit" class="liste_titre button_search reposition" name="button_search_x" value="x"><span class="fas fa-search"></span></button>';
12564 $out .=
'<button type="submit" class="liste_titre button_removefilter reposition" name="button_removefilter_x" value="x"><span class="fas fa-times"></span></button>';
12578 public function showCheckAddButtons($cssclass =
'checkforaction', $calljsfunction = 0, $massactionname =
"massaction")
12584 if (!empty(
$conf->use_javascript_ajax)) {
12585 $out .=
'<div class="inline-block checkallactions"><input type="checkbox" id="' . $cssclass .
's" name="' . $cssclass .
's" class="checkallactions"></div>';
12587 $out .=
'<script nonce="' .
getNonce() .
'">
12588 $(document).ready(function() {
12589 $("#' . $cssclass .
's").click(function() {
12590 if($(this).is(\':checked\')){
12591 console.log("We check all ' . $cssclass .
' and trigger the change method");
12592 $(".' . $cssclass .
'").prop(\'checked\', true).trigger(\'change\');
12596 console.log("We uncheck all");
12597 $(".' . $cssclass .
'").prop(\'checked\', false).trigger(\'change\');
12599 if ($calljsfunction) {
12600 $out .=
'if (typeof initCheckForSelect == \'function\') { initCheckForSelect(0, "' . $massactionname .
'", "' . $cssclass .
'"); } else { console.log("No function initCheckForSelect found. Call won\'t be done."); }';
12603 $(".' . $cssclass .
'").change(function() {
12604 console.log("We check and change the tr class highlight after a change on .'.$cssclass.
'");
12605 var $row = $(this).closest("tr");
12607 var anyChecked = $row.find(\'input[type="checkbox"].' . $cssclass .
':checked\').length > 0;
12608 console.log("anychecked="+anyChecked);
12610 $row.removeClass("highlight");
12612 $row.addClass("highlight");
12633 $out = $this->showFilterButtons();
12634 if ($addcheckuncheckall) {
12635 $out .= $this->showCheckAddButtons($cssclass, $calljsfunction, $massactionname);
12653 public function selectExpenseCategories($selected =
'', $htmlname =
'fk_c_exp_tax_cat', $useempty = 0, $excludeid = array(), $target =
'', $default_selected = 0, $params = array(), $info_admin = 1)
12655 global $langs, $user;
12658 $sql =
"SELECT rowid, label FROM " . $this->db->prefix() .
"c_exp_tax_cat WHERE active = 1";
12659 $sql .=
" AND entity IN (0," .
getEntity(
'exp_tax_cat') .
")";
12660 if (!empty($excludeid)) {
12661 $sql .=
" AND rowid NOT IN (" . $this->db->sanitize(implode(
',', $excludeid)) .
")";
12663 $sql .=
" ORDER BY label";
12665 $resql = $this->db->query($sql);
12667 $out =
'<select id="select_' . $htmlname .
'" name="' . $htmlname .
'" class="' . $htmlname .
' flat minwidth75imp maxwidth200">';
12669 $out .=
'<option value="0"> </option>';
12672 while ($obj = $this->db->fetch_object($resql)) {
12673 $out .=
'<option ' . ($selected == $obj->rowid ?
'selected="selected"' :
'') .
' value="' . $obj->rowid .
'">' . $langs->trans($obj->label) .
'</option>';
12675 $out .=
'</select>';
12678 if (!empty($htmlname) && $user->admin && $info_admin) {
12679 $out .=
' ' .
info_admin($langs->trans(
"YouCanChangeValuesForThisListFromDictionarySetup"), 1);
12682 if (!empty($target)) {
12683 $sql =
"SELECT c.id FROM " . $this->db->prefix() .
"c_type_fees as c WHERE c.code = 'EX_KME' AND c.active = 1";
12684 $resql = $this->db->query($sql);
12686 if ($this->db->num_rows($resql) > 0) {
12687 $obj = $this->db->fetch_object($resql);
12688 $out .=
'<script nonce="' .
getNonce() .
'">
12690 $("select[name=' . $target .
']").on("change", function() {
12691 var current_val = $(this).val();
12692 if (current_val == ' . $obj->id .
') {';
12693 if (!empty($default_selected) || !empty($selected)) {
12694 $out .=
'$("select[name=' . $htmlname .
']").val("' . ($default_selected > 0 ? $default_selected : $selected) .
'");';
12698 $("select[name=' . $htmlname .
']").change();
12702 $("select[name=' . $htmlname .
']").change(function() {
12704 if ($("select[name=' . $target .
']").val() == ' . $obj->id .
') {
12705 // get price of kilometer to fill the unit price
12709 data: { fk_c_exp_tax_cat: $(this).val(), token: \'' .
currentToken() .
'\' },
12710 url:
"' . (DOL_URL_ROOT . '/expensereport/ajax/ajaxik.php?' . implode('&', $params)) . '",
12711 }).done(
function( data, textStatus, jqXHR ) {
12713 if (typeof data.up !=
"undefined") {
12714 $(
"input[name=value_unit]").val(data.up);
12715 $(
"select[name=' . $htmlname . ']").attr(
"title", data.title);
12717 $(
"input[name=value_unit]").val(
"");
12718 $(
"select[name=' . $htmlname . ']").attr(
"title",
"");
12729 dol_print_error($this->db);
12743 public function selectExpenseRanges($selected = '
', $htmlname = 'fk_range
', $useempty = 0)
12745 global $conf, $langs;
12748 $sql = "SELECT rowid, range_ik FROM " . $this->db->prefix() . "c_exp_tax_range";
12749 $sql .= " WHERE entity = " . ((int) $conf->entity) . " AND active = 1";
12751 $resql = $this->db->query($sql);
12753 $out = '<select
id=
"select_' . $htmlname . '" name=
"' . $htmlname . '" class=
"' . $htmlname . ' flat minwidth75imp">
';
12755 $out .= '<option value=
"0"></option>
';
12758 while ($obj = $this->db->fetch_object($resql)) {
12759 $out .= '<option
' . ($selected == $obj->rowid ? 'selected=
"selected"' : '') . ' value=
"' . $obj->rowid . '">
' . price($obj->range_ik, 0, $langs, 1, 0) . '</option>
';
12761 $out .= '</select>
';
12763 dol_print_error($this->db);
12779 public function selectExpenseFees($selected = '
', $htmlname = 'fk_c_type_fees
', $useempty = 0, $allchoice = 1, $useid = 0)
12784 $sql = "SELECT id, code, label";
12785 $sql .= " FROM ".$this->db->prefix()."c_type_fees";
12786 $sql .= " WHERE active = 1";
12788 $resql = $this->db->query($sql);
12790 $out = '<select
id=
"select_' . $htmlname . '" name=
"' . $htmlname . '" class=
"' . $htmlname . ' flat minwidth75imp">
';
12792 $out .= '<option value=
"0"></option>
';
12795 $out .= '<option value=
"-1">
' . $langs->trans('AllExpenseReport
') . '</option>
';
12803 while ($obj = $this->db->fetch_object($resql)) {
12804 $key = $langs->trans($obj->code);
12805 $out .= '<option
' . ($selected == $obj->{$field} ? 'selected=
"selected"' : '') . ' value=
"' . $obj->{$field} . '">
' . ($key != $obj->code ? $key : $obj->label) . '</option>
';
12807 $out .= '</select>
';
12809 $out .= ajax_combobox('select_
'.$htmlname);
12811 dol_print_error($this->db);
12835 public function selectInvoiceForTimeProject($socid = -1, $selected = '
', $htmlname = 'invoiceid
', $maxlength = 24, $option_only = 0, $show_empty = '1
', $discard_closed = 0, $forcefocus = 0, $disabled = 0, $morecss = 'maxwidth500
', $projectsListId = '', $showproject = 'all
', $usertofilter = null)
12837 global $user, $conf, $langs;
12839 require_once DOL_DOCUMENT_ROOT . '/projet/
class/project.class.php
';
12841 if (is_null($usertofilter)) {
12842 $usertofilter = $user;
12847 $hideunselectables = false;
12848 if (getDolGlobalString('INVOICE_HIDE_UNSELECTABLES
')) {
12849 $hideunselectables = true;
12852 if (empty($projectsListId)) {
12853 if (!$usertofilter->hasRight('projet
', 'all
', 'lire
')) {
12854 $projectstatic = new Project($this->db);
12855 $projectsListId = $projectstatic->getProjectsAuthorizedForUser($usertofilter, 0, 1);
12859 // Search all projects
12860 $sql = "SELECT f.rowid, f.ref as fref, 'nolabel
' as flabel, p.rowid as pid, f.ref, p.title, p.fk_soc, p.fk_statut, p.public, s.nom as name";
12861 $sql .= " FROM " . $this->db->prefix() . "facture as f";
12862 $sql .= " INNER JOIN " . $this->db->prefix() . "projet as p ON p.entity IN (" . getEntity('project
') . ") AND f.fk_projet = p.rowid";
12863 $sql .= " LEFT JOIN " . $this->db->prefix() . "societe as s ON s.rowid = p.fk_soc";
12864 $sql .= " WHERE f.fk_statut = 0"; // Draft invoices only
12865 //if ($projectsListId) $sql.= " AND p.rowid IN (".$this->db->sanitize($projectsListId).")";
12866 //if ($socid == 0) $sql.= " AND (p.fk_soc=0 OR p.fk_soc IS NULL)";
12867 //if ($socid > 0) $sql.= " AND (p.fk_soc=".((int) $socid)." OR p.fk_soc IS NULL)";
12868 $sql .= " ORDER BY p.ref, f.ref ASC";
12870 $resql = $this->db->query($sql);
12872 // Use select2 selector
12873 if (!empty($conf->use_javascript_ajax)) {
12874 include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php
';
12875 $comboenhancement = ajax_combobox($htmlname, array(), 0, $forcefocus);
12876 $out .= $comboenhancement;
12877 $morecss = 'minwidth200imp maxwidth500
';
12880 if (empty($option_only)) {
12881 $out .= '<select
class=
"valignmiddle flat' . ($morecss ? ' ' . $morecss : '') . '"' . ($disabled ? ' disabled=
"disabled"' : '') . ' id=
"' . $htmlname . '" name=
"' . $htmlname . '">
';
12883 if (!empty($show_empty)) {
12884 $out .= '<option value=
"0" class=
"optiongrey">
';
12885 if (!is_numeric($show_empty)) {
12886 $out .= $show_empty;
12890 $out .= '</option>
';
12892 $num = $this->db->num_rows($resql);
12895 while ($i < $num) {
12896 $obj = $this->db->fetch_object($resql);
12897 // If we ask to filter on a company and user has no permission to see all companies and project is linked to another company, we hide project.
12898 if ($socid > 0 && (empty($obj->fk_soc) || $obj->fk_soc == $socid) && !$usertofilter->hasRight('societe
', 'lire
')) {
12901 if ($discard_closed == 1 && $obj->fk_statut == Project::STATUS_CLOSED) {
12908 if ($showproject == 'all
') {
12909 $labeltoshow .= dol_trunc($obj->ref, 18); // Invoice ref
12911 $labeltoshow .= ' -
' . $obj->name; // Soc name
12915 if ($obj->fk_statut == Project::STATUS_DRAFT) {
12917 $labeltoshow .= ' -
' . $langs->trans("Draft");
12918 } elseif ($obj->fk_statut == Project::STATUS_CLOSED) {
12919 if ($discard_closed == 2) {
12922 $labeltoshow .= ' -
' . $langs->trans("Closed");
12923 } elseif ($socid > 0 && (!empty($obj->fk_soc) && $obj->fk_soc != $socid)) {
12925 $labeltoshow .= ' -
' . $langs->trans("LinkedToAnotherCompany");
12929 if (!empty($selected) && $selected == $obj->rowid) {
12930 $out .= '<option value=
"' . $obj->rowid . '" selected
';
12931 //if ($disabled) $out.=' disabled'; // with select2, field can't be preselected
if disabled
12932 $out .=
'>' . $labeltoshow .
'</option>';
12934 if ($hideunselectables && $disabled && ($selected != $obj->rowid)) {
12937 $resultat =
'<option value="' . $obj->rowid .
'"';
12939 $resultat .=
' disabled';
12944 $resultat .= $labeltoshow;
12945 $resultat .=
'</option>';
12953 if (empty($option_only)) {
12954 $out .=
'</select>';
12957 $this->db->free($resql);
12961 dol_print_error($this->db);
12980 public function selectInvoiceRec($selected =
'', $htmlname =
'facrecid', $maxlength = 24, $option_only = 0, $show_empty =
'1', $forcefocus = 0, $disabled = 0, $morecss =
'maxwidth500')
12982 global
$conf, $langs;
12988 $sql =
'SELECT f.rowid, f.entity, f.titre as title, f.suspended, f.fk_soc';
12989 $sql .=
' FROM ' . MAIN_DB_PREFIX .
'facture_rec as f';
12990 $sql .=
" WHERE f.entity IN (" .
getEntity(
'invoice') .
")";
12991 $sql .=
" ORDER BY f.titre ASC";
12993 $resql = $this->db->query($sql);
12996 if (!empty(
$conf->use_javascript_ajax)) {
12997 include_once DOL_DOCUMENT_ROOT .
'/core/lib/ajax.lib.php';
12998 $comboenhancement =
ajax_combobox($htmlname, array(), 0, $forcefocus);
12999 $out .= $comboenhancement;
13000 $morecss =
'minwidth200imp maxwidth500';
13003 if (empty($option_only)) {
13004 $out .=
'<select class="valignmiddle flat' . ($morecss ?
' ' . $morecss :
'') .
'"' . ($disabled ?
' disabled="disabled"' :
'') .
' id="' . $htmlname .
'" name="' . $htmlname .
'">';
13006 if (!empty($show_empty)) {
13007 $out .=
'<option value="0" class="optiongrey">';
13008 if (!is_numeric($show_empty)) {
13009 $out .= $show_empty;
13013 $out .=
'</option>';
13015 $num = $this->db->num_rows($resql);
13017 while ($obj = $this->db->fetch_object($resql)) {
13018 $labeltoshow =
dol_trunc($obj->title, 18);
13021 if (!empty($obj->suspended)) {
13023 $labeltoshow .=
' - ' . $langs->trans(
"Closed");
13027 if (!empty($selected) && $selected == $obj->rowid) {
13028 $out .=
'<option value="' . $obj->rowid .
'" selected';
13030 $out .=
'>' . $labeltoshow .
'</option>';
13032 if ($disabled && ($selected != $obj->rowid)) {
13035 $resultat =
'<option value="' . $obj->rowid .
'"';
13037 $resultat .=
' disabled';
13040 $resultat .= $labeltoshow;
13041 $resultat .=
'</option>';
13047 if (empty($option_only)) {
13048 $out .=
'</select>';
13053 $this->db->free($resql);
13056 $this->errors[] = $this->db->lasterror;
13072 public function searchComponent($arrayofcriterias, $search_component_params, $arrayofinputfieldsalreadyoutput = array(), $search_component_params_hidden =
'', $arrayoffiltercriterias = array())
13075 global $langs, $form;
13080 if ($search_component_params_hidden !=
'' && !preg_match(
'/^\(.*\)$/', $search_component_params_hidden)) {
13081 $search_component_params_hidden =
'(' . $search_component_params_hidden .
')';
13084 $ret =
'<!-- searchComponent -->';
13086 $ret .=
'<div class="divadvancedsearchfieldcomp centpercent inline-block">';
13087 $ret .=
'<a href="#" class="dropdownsearch-toggle unsetcolor">';
13088 $ret .=
'<span class="fas fa-filter linkobject boxfilter paddingright pictofixedwidth" title="' .
dol_escape_htmltag($langs->trans(
"Filters")) .
'" id="idsubimgproductdistribution"></span>';
13091 $ret .=
'<div class="divadvancedsearchfieldcompinput centpercentminusx inline-block minwidth500 maxwidth300onsmartphone">';
13094 $ret .=
'<div id="divsearch_component_params" name="divsearch_component_params" class="noborderbottom search_component_params inline-block valignmiddle">';
13096 if ($search_component_params_hidden) {
13104 foreach ($arrayofandtags as $tmpkey => $tmpval) {
13105 $errormessage =
'';
13107 if ($errormessage) {
13108 $this->error =
'ERROR in parsing search string: '.$errormessage;
13111 include_once DOL_DOCUMENT_ROOT.
'/core/lib/functions2.lib.php';
13114 $ret .=
'<span class="marginleftonlyshort valignmiddle tagsearch" data-ufilterid="'.($tmpkey + 1).
'" data-ufilter="'.
dol_escape_htmltag($tmpval).
'">';
13115 $ret .=
'<span class="tagsearchdelete select2-selection__choice__remove" data-ufilterid="'.($tmpkey + 1).
'">x</span> ';
13127 $show_search_component_params_hidden = 1;
13128 if ($show_search_component_params_hidden) {
13129 $ret .=
'<input type="hidden" name="show_search_component_params_hidden" value="1">';
13131 $ret .=
"<!-- We store the full Universal Search String into this field. For example: (t.ref:like:'SO-%') AND ((t.ref:like:'CO-%') OR (t.ref:like:'AA%')) -->";
13132 $ret .=
'<input type="hidden" id="search_component_params_hidden" name="search_component_params_hidden" value="' .
dol_escape_htmltag($search_component_params_hidden) .
'">';
13137 foreach ($arrayofcriterias as $criteria) {
13138 foreach ($criteria as $criteriafamilykey => $criteriafamilyval) {
13139 if (in_array(
'search_' . $criteriafamilykey, $arrayofinputfieldsalreadyoutput)) {
13142 if (in_array($criteriafamilykey, array(
'rowid',
'ref_ext',
'entity',
'extraparams'))) {
13145 if (in_array($criteriafamilyval[
'type'], array(
'date',
'datetime',
'timestamp'))) {
13146 $ret .=
'<input type="hidden" name="search_' . $criteriafamilykey .
'_start">';
13147 $ret .=
'<input type="hidden" name="search_' . $criteriafamilykey .
'_startyear">';
13148 $ret .=
'<input type="hidden" name="search_' . $criteriafamilykey .
'_startmonth">';
13149 $ret .=
'<input type="hidden" name="search_' . $criteriafamilykey .
'_startday">';
13150 $ret .=
'<input type="hidden" name="search_' . $criteriafamilykey .
'_end">';
13151 $ret .=
'<input type="hidden" name="search_' . $criteriafamilykey .
'_endyear">';
13152 $ret .=
'<input type="hidden" name="search_' . $criteriafamilykey .
'_endmonth">';
13153 $ret .=
'<input type="hidden" name="search_' . $criteriafamilykey .
'_endday">';
13155 $ret .=
'<input type="hidden" name="search_' . $criteriafamilykey .
'">';
13162 $ret .=
"<!-- Field to enter a generic filter string: t.ref:like:'SO-%', t.date_creation:>:'20160101', t.date_creation:<:'2016-01-01 12:30:00', t.nature:is:NULL, t.field2:isnot:NULL -->\n";
13163 $ret .=
'<input type="text" placeholder="' . $langs->trans(
"Filters") .
'" id="search_component_params_input" name="search_component_params_input" class="noborderall search_component_input" value="">';
13169 jQuery(".tagsearchdelete").click(function(e) {
13170 var filterid = $(this).parents().attr("data-ufilterid");
13171 console.log("We click to delete the criteria nb "+filterid);
13173 // Regenerate the search_component_params_hidden with all data-ufilter except the one to delete, and post the page
13174 var newparamstring = \'\';
13175 $(\'.tagsearch\').each(function(index, element) {
13176 tmpfilterid = $(this).attr("data-ufilterid");
13177 if (tmpfilterid != filterid) {
13178 // We keep this criteria
13179 if (newparamstring == \'\') {
13180 newparamstring = $(this).attr("data-ufilter");
13182 newparamstring = newparamstring + \' AND \' + $(this).attr("data-ufilter");
13186 console.log("newparamstring = "+newparamstring);
13188 jQuery("#search_component_params_hidden").val(newparamstring);
13190 // We repost the form
13191 $(this).closest(\'form\').submit();
13194 jQuery("#search_component_params_input").keydown(function(e) {
13195 console.log("We press a key on the filter field that is "+jQuery("#search_component_params_input").val());
13196 console.log(e.which);
13197 if (jQuery("#search_component_params_input").val() == "" && e.which == 8) {
13198 /* We click on back when the input field is already empty */
13199 event.preventDefault();
13200 jQuery("#divsearch_component_params .tagsearch").last().remove();
13201 /* Regenerate content of search_component_params_hidden from remaining .tagsearch */
13203 jQuery("#divsearch_component_params .tagsearch").each(function( index ) {
13207 s = s + $(this).attr("data-ufilter");
13209 console.log("New value for search_component_params_hidden = "+s);
13210 jQuery("#search_component_params_hidden").val(s);
13218 $arrayoffiltercriterias_json = json_encode($arrayoffiltercriterias);
13223 $arrayoffilterelements = array();
13224 foreach ($arrayoffiltercriterias as $key => $val) {
13226 $tmpelementkey = preg_replace(
'/\.[^.]*$/',
'', $key);
13228 $tmpelementkey = preg_replace(
'/^te(__|$)/',
't$1', $tmpelementkey);
13230 $tmpelementlabel = $tmpelementkey;
13231 $tmpelementpicto =
'';
13232 $tmpfieldlabel = $key;
13233 if (!empty($val[
'labelnohtml'])) {
13234 $tmpfieldlabel = $val[
'labelnohtml'];
13236 if (preg_match(
'/^(.+?): /', $val[
'labelnohtml'], $tmpmatch)) {
13237 $tmpelementlabel = $tmpmatch[1];
13238 $tmpfieldlabel = trim(substr($val[
'labelnohtml'], strlen($tmpelementlabel) + 1));
13240 if (!empty($val[
'label'])) {
13242 $tmpelementpicto = trim(str_replace($val[
'labelnohtml'],
'', $val[
'label']));
13246 if (!isset($arrayoffilterelements[$tmpelementkey])) {
13247 $arrayoffilterelements[$tmpelementkey] = array(
'picto' => $tmpelementpicto,
'label' => $tmpelementlabel,
'fields' => array());
13249 $arrayoffilterelements[$tmpelementkey][
'fields'][$key] = array(
'label' => $tmpfieldlabel,
'type' => $val[
'type']);
13252 var arrayoffiltercriterias = ' . $arrayoffiltercriterias_json .
';
13257 $ret .=
'<div class="search-component-assistance">';
13260 $ret .=
'<p class="assistance-title">' . img_picto(
'',
'filter') .
' ' . $langs->trans(
'FilterAssistance') .
' </p>';
13262 $ret .=
'<p class="assistance-errors error" style="display:none">' . $langs->trans(
'AllFieldsRequired') .
' </p>';
13267 $ret .=
'<div class="operand valigntop">';
13268 $ret .=
'<div class="fieldcombo">';
13270 $ret .=
'<input type="hidden" id="search_filter_field" name="search_filter_field" value="">';
13272 $ret .=
'<button type="button" class="fieldcombo-toggle"><span class="fieldcombo-label opacitymedium">' .
dol_escape_htmltag($langs->trans(
'Fields')) .
'</span><span class="fas fa-caret-down fieldcombo-caret"></span></button>';
13276 $ret .=
'<div class="fieldcombo-panel" style="display:none">';
13277 $ret .=
'<div class="liinputsearch"><input type="text" class="fieldcombo-search noborderfocus" placeholder="' .
dol_escape_htmltag($langs->trans(
'Search')) .
'"></div>';
13278 $ret .=
'<div class="fieldcombo-list">';
13284 $renderElementCombo =
null;
13285 $renderElementCombo =
function ($tmpelementkey) use ($arrayoffilterelements, &$renderElementCombo) {
13286 $tmpelementval = $arrayoffilterelements[$tmpelementkey];
13287 $arrayofchildelementkeys = array();
13288 foreach ($arrayoffilterelements as $tmpchildelementkey => $tmpchildelementval) {
13289 if (strpos($tmpchildelementkey, $tmpelementkey.
'__') === 0 && strpos(substr($tmpchildelementkey, strlen($tmpelementkey) + 2),
'__') ===
false) {
13290 $arrayofchildelementkeys[] = $tmpchildelementkey;
13294 $out .=
'<div class="fieldcombo-element" data-element="' . dolPrintHTMLForAttribute($tmpelementkey) .
'">';
13295 $out .=
'<div class="fieldcombo-elementheader" tabindex="0"><span class="fieldcombo-elementlabel">' . $tmpelementval[
'picto'] .
' ' .
dol_escape_htmltag($tmpelementval[
'label']) .
'</span><span class="fas fa-caret-right fieldcombo-elementcaret"></span></div>';
13297 $out .=
'<div class="fieldcombo-fields" style="display:none">';
13298 foreach ($tmpelementval[
'fields'] as $tmpfieldkey => $tmpfieldval) {
13299 $out .=
'<div class="fieldcombo-field" tabindex="0" data-field="' . dolPrintHTMLForAttribute($tmpfieldkey) .
'" data-type="' . dolPrintHTMLForAttribute($tmpfieldval[
'type']) .
'">' .
dol_escape_htmltag($tmpfieldval[
'label']) .
'</div>';
13302 if (!empty($arrayofchildelementkeys)) {
13305 $out .=
'<div class="fieldcombo-children" style="display:none">';
13306 foreach ($arrayofchildelementkeys as $tmpchildelementkey) {
13307 $out .= $renderElementCombo($tmpchildelementkey);
13315 foreach ($arrayoffilterelements as $tmpelementkey => $tmpelementval) {
13317 $tmpparentkey =
'';
13318 if (strpos($tmpelementkey,
'__') !==
false) {
13319 $tmparrayofkey = explode(
'__', $tmpelementkey);
13320 array_pop($tmparrayofkey);
13321 $tmpparentkey = implode(
'__', $tmparrayofkey);
13325 if ($tmpparentkey ==
'' || !isset($arrayoffilterelements[$tmpparentkey])) {
13326 $ret .= $renderElementCombo($tmpelementkey);
13334 $ret .=
'<span class="separator"></span>';
13337 $ret .=
'<div class="operator valigntop">';
13338 $ret .=
'<select class="operator-selector width150" id="operator-selector"">';
13339 $ret .=
'</select>';
13340 $ret .=
'<script>$(document).ready(function() {';
13341 $ret .=
' $(".operator-selector").select2({';
13342 $ret .=
' placeholder: \'' .
dol_escape_js($langs->transnoentitiesnoconv(
'Operator')) .
'\'';
13344 $ret .=
'});</script>';
13347 $ret .=
'<span class="separator"></span>';
13349 $ret .=
'<div class="value valigntop">';
13351 $ret .=
'<input type="text" class="flat width100 value-input" placeholder="' . dolPrintHTML($langs->trans(
'Value')) .
'">';
13355 $ret .=
'<span class="date-one" style="display:none">';
13356 $ret .= $form->selectDate(($dateOne ? $dateOne : -1),
'dateone', 0, 0, 1,
'', 1, 0, 0,
'',
'',
'',
'', 1,
'');
13360 $ret .=
'<select class="value-selector width150" id="value-selector" style="display:none">';
13361 $ret .=
'</select>';
13363 $(document).ready(function() {
13364 $("#value-selector").select2({
13365 placeholder: \'' .
dol_escape_js($langs->trans(
'Value')) .
'\'
13367 $(
"#value-selector").hide();
13368 $(
"#value-selector").next(
".select2-container").hide();
13374 $ret .= '<div
class=
"btn-div">
';
13375 $ret .= '<
button class=
"button buttongen button-save add-filter-btn" type=
"button">
' . $langs->trans("addToFilter") . '</
button>
';
13379 //$ret .= '</tbody></
table>
';
13381 // End of the assistance div
13384 // Script jQuery to show/hide the floating assistance
13386 $(document).ready(
function() {
13387 $(
"#search_component_params_input").on(
"click",
function() {
13388 const inputPosition = $(
this).offset();
13389 const inputHeight = $(
this).outerHeight();
13390 $(
".search-component-assistance").css({
13391 top: inputPosition.top + inputHeight + 5 +
"px",
13392 left: $(
"#divsearch_component_params").position().left
13393 }).slideToggle(200);
13395 $(document).on(
"click",
function(e) {
13396 if (!$(e.target).closest(
"#search_component_params_input, .search-component-assistance, #ui-datepicker-div").length) {
13397 $(
".search-component-assistance").hide();
13404 $(document).ready(
function() {
13406 function resetValueInputs() {
13407 $(
".value-input, .dateone, .datemonth, .dateyear").val(
"").hide();
13408 $(
"#datemonth, #dateyear").val(
null).trigger(
"change.select2");
13409 $(
"#dateone").datepicker(
"setDate",
null);
13410 $(
".date-one, .date-month, .date-year").hide();
13411 $(
"#value-selector").val(
"").hide();
13412 $(
"#value-selector").next(
".select2-container").hide();
13413 $(
"#value-selector").val(
null).trigger(
"change.select2");
13417 function resetOperatorAndValueInputs() {
13418 $(
".operator-selector").empty();
13419 resetValueInputs();
13424 $(
".fieldcombo-toggle").on(
"click",
function(e) {
13425 e.stopPropagation();
13426 $(
this).closest(
".fieldcombo").find(
".fieldcombo-panel").toggle();
13429 $(
this).closest(
".fieldcombo").find(
".fieldcombo-search").val(
"").trigger(
"keyup");
13434 $(
".fieldcombo-elementheader").on(
"click",
function(e) {
13435 e.stopPropagation();
13436 const elementdiv = $(
this).closest(
".fieldcombo-element");
13437 const wasopen = elementdiv.hasClass(
"open");
13438 $(
".fieldcombo-element").removeClass(
"open");
13439 $(
".fieldcombo-fields, .fieldcombo-children").hide();
13440 $(
".fieldcombo-field").show();
13441 elementdiv.parents(
".fieldcombo-element").addClass(
"open").show().children(
".fieldcombo-fields, .fieldcombo-children").show();
13443 elementdiv.addClass(
"open").show().children(
".fieldcombo-fields, .fieldcombo-children").show();
13448 $(
".fieldcombo-field").on(
"click",
function(e) {
13449 e.stopPropagation();
13450 const fieldlabel = $(
this).text();
13451 const elementlabelhtml = $(
this).closest(
".fieldcombo-element").find(
".fieldcombo-elementlabel").html();
13452 $(
".fieldcombo-field").removeClass(
"selected");
13453 $(
this).addClass(
"selected");
13454 $(
".fieldcombo-label").html(elementlabelhtml).removeClass(
"opacitymedium").append(document.createTextNode(
": " + fieldlabel));
13455 $(
"#search_filter_field").attr(
"data-type", $(
this).attr(
"data-type")).val($(
this).attr(
"data-field"));
13456 $(
".fieldcombo-panel").hide();
13457 $(
"#search_filter_field").trigger(
"change");
13461 $(
".fieldcombo-search").on(
"keyup change",
function() {
13462 const term = $(
this).val().toLowerCase();
13466 $(
".fieldcombo-element").removeClass(
"open").show();
13467 $(
".fieldcombo-fields, .fieldcombo-children").hide();
13468 $(
".fieldcombo-field").show();
13469 $(
".fieldcombo-list > .fieldcombo-element").addClass(
"open").children(
".fieldcombo-fields, .fieldcombo-children").show();
13474 $(
".fieldcombo-element").each(
function() {
13475 const elementmatch = $(
this).children(
".fieldcombo-elementheader").find(
".fieldcombo-elementlabel").text().toLowerCase().indexOf(term) > -1;
13476 let hasfieldmatch =
false;
13477 $(
this).children(
".fieldcombo-fields").children(
".fieldcombo-field").each(
function() {
13478 const fieldmatch = elementmatch || $(
this).text().toLowerCase().indexOf(term) > -1;
13479 $(
this).toggle(fieldmatch);
13481 hasfieldmatch =
true;
13484 $(
this).toggleClass(
"open", elementmatch || hasfieldmatch);
13485 $(
this).children(
".fieldcombo-fields").toggle(elementmatch || hasfieldmatch);
13487 $(
".fieldcombo-element").each(
function() {
13488 if ($(
this).hasClass(
"open")) {
13491 $(
this).parents(
".fieldcombo-element").addClass(
"open").show().children(
".fieldcombo-children").show();
13499 $(document).on(
"keydown",
function(e) {
13500 if (e.which === 27) {
13501 $(
".fieldcombo-panel").hide();
13504 $(
".fieldcombo-elementheader, .fieldcombo-field").on(
"keydown",
function(e) {
13505 if (e.which === 13) {
13506 e.preventDefault();
13507 $(this).trigger(
"click");
13512 $(document).on(
"click",
function(e) {
13513 if (!$(e.target).closest(
".fieldcombo").length) {
13514 $(
".fieldcombo-panel").hide();
13518 $(
"#search_filter_field").on(
"change",
function() {
13519 console.log(
"We change search_filter_field");
13522 let fieldType = $(
this).attr(
"data-type");
13523 const selectedFieldValue = $(
this).val();
13526 if (arrayoffiltercriterias[selectedFieldValue] === undefined) {
13527 resetOperatorAndValueInputs();
13532 if (arrayoffiltercriterias[selectedFieldValue][
"arrayofkeyval"] !== undefined) {
13533 fieldType =
"select";
13537 if (arrayoffiltercriterias[selectedFieldValue][
"maybenull"] !== undefined) {
13540 const operators = getOperatorsForFieldType(fieldType, maybenull);
13541 const operatorSelector = $(
".operator-selector");
13544 operatorSelector.empty();
13547 Object.entries(operators).forEach(
function([
operator, label]) {
13548 operatorSelector.append(
"<option value=\'" +
operator +
"\'>" + label +
"</option>");
13551 operatorSelector.trigger(
"change.select2");
13554 resetValueInputs();
13556 if (fieldType ===
"date" || fieldType ===
"datetime" || fieldType ===
"timestamp") {
13557 $(
".date-one").show();
13558 }
else if (arrayoffiltercriterias[selectedFieldValue][
"arrayofkeyval"] !== undefined) {
13559 var arrayofkeyval = arrayoffiltercriterias[selectedFieldValue][
"arrayofkeyval"];
13560 var valueSelector = $(
"#value-selector");
13561 valueSelector.empty();
13562 Object.entries(arrayofkeyval).forEach(
function([key, val]) {
13563 valueSelector.append(
"<option value=\'" + key +
"\'>" + val +
"</option>");
13565 valueSelector.trigger(
"change.select2");
13567 $(
"#value-selector").show();
13568 $(
"#value-selector").next(
".select2-container").show();
13570 $(
".value-input").show();
13574 $(
"#operator-selector").on(
"change",
function() {
13575 console.log(
"We change operator-selector");
13577 const selectedOperator = $(
this).find(
":selected").val();
13578 if (selectedOperator ===
"IsDefined" || selectedOperator ===
"IsNotDefined") {
13580 $(
".value-input, .dateone, .datemonth, .dateyear").val(
"").prop(
"disabled",
true);
13581 $(
"#datemonth, #dateyear").val(
null).trigger(
"change.select2");
13582 $(
"#dateone").datepicker(
"setDate",
null).datepicker(
"option",
"disabled",
true);
13583 $(
".date-one, .date-month, .date-year").prop(
"disabled",
true);
13584 $(
"#value-selector").val(
"").prop(
"disabled",
true);
13585 $(
"#value-selector").val(
null).trigger(
"change.select2");
13588 $(
".value-input, .dateone, .datemonth, .dateyear").prop(
"disabled",
false);
13589 $(
".date-one, .date-month, .date-year").prop(
"disabled",
false);
13590 $(
"#dateone").datepicker(
"option",
"disabled",
false);
13591 $(
"#value-selector").prop(
"disabled",
false);
13595 $(
".add-filter-btn").on(
"click",
function(event) {
13596 console.log(
"We click on add-filter-btn");
13598 event.preventDefault();
13600 const field = $(
"#search_filter_field").val();
13601 const operator = $(
".operator-selector").val();
13602 let value = $(
".value-input").val();
13603 const fieldType = $(
"#search_filter_field").attr(
"data-type");
13605 if ([
"date",
"datetime",
"timestamp"].includes(fieldType)) {
13606 const year = $(
"#dateoneyear").val().toString().padStart(4,
"0");;
13607 const month = $(
"#dateonemonth").val().toString().padStart(2,
"0");
13608 const day = $(
"#dateoneday").val().toString().padStart(2,
"0");
13609 value = `${year}-${month}-${day}`;
13610 console.log(
"value="+value);
13614 if (arrayoffiltercriterias[field] !== undefined && arrayoffiltercriterias[field][
"arrayofkeyval"] !== undefined) {
13615 value = $(
"#value-selector").val();
13619 if (
operator ===
"IsDefined" ||
operator ===
"IsNotDefined") {
13623 const filterString = generateFilterString(field,
operator, value, fieldType);
13626 if (filterString !==
"" && field !==
"" && field !==
"-1" && field !==
null &&
operator !==
"" &&
operator !==
null && value !==
"" && value !==
null) {
13627 $(
"#search_component_params_input").val($(
"#search_component_params_input").val() +
" " + filterString);
13628 $(
"#search_component_params_input").closest(
"form").submit();
13630 $(
".assistance-errors").show();
13650 public function selectModelMail($prefix, $modelType = '
', $default = 0, $addjscombo = 0, $selected = 0, $morecss = '')
13652 global $langs, $user;
13656 $TModels = array();
13658 include_once DOL_DOCUMENT_ROOT . '/core/
class/html.formmail.class.php
';
13659 $formmail = new FormMail($this->db);
13660 $result = $formmail->fetchAllEMailTemplate($modelType, $user, $langs);
13663 $TModels[0] = $langs->trans('DefaultMailModel
');
13666 foreach ($formmail->lines_model as $model) {
13667 $TModels[(int) $model->id] = $model->label;
13671 $retstring .= '<select
class=
"flat'.($morecss ? ' '.$morecss : '').'" id=
"select_' . $prefix . 'model_mail" name=
"' . $prefix . 'model_mail">
';
13673 foreach ($TModels as $id_model => $label_model) {
13674 $retstring .= '<option value=
"' . $id_model . '"';
13675 if (!empty($selected) && ((int) $selected) == $id_model) {
13676 $retstring .= "selected";
13678 $retstring .= ">" . $label_model . "</option>";
13681 $retstring .= "</select>";
13684 $retstring .= ajax_combobox('select_
' . $prefix . 'model_mail
');
13701 public function buttonsSaveCancel($save_label = 'Save
', $cancel_label = 'Cancel
', $morebuttons = array(), $withoutdiv = false, $morecss = '', $dol_openinpopup = '')
13705 $buttons = array();
13709 'label_key
' => $save_label,
13712 if ($save_label == 'Create
' || $save_label == 'Add
') {
13713 $save['name'] = 'add
';
13714 } elseif ($save_label == 'Modify
') {
13715 $save['name'] = 'edit
';
13719 'name' => 'cancel
',
13720 'label_key
' => 'Cancel
',
13723 // If MAIN_BUTTON_POSITION_FIRST_OR_LEFT not set, default is to have main action first, then complementary, then cancel at end
13724 if (!getDolGlobalInt('MAIN_BUTTON_POSITION_FIRST_OR_LEFT
')) {
13725 !empty($save_label) ? $buttons[] = $save : '';
13726 if (!empty($morebuttons)) {
13727 $buttons[] = $morebuttons;
13729 !empty($cancel_label) ? $buttons[] = $cancel : '';
13731 if (!empty($morebuttons)) {
13732 $buttons[] = $morebuttons;
13734 !empty($cancel_label) ? $buttons[] = $cancel : '';
13735 !empty($save_label) ? $buttons[] = $save : '';
13738 $retstring = $withoutdiv ? '' : '<div
class=
"center">
';
13740 foreach ($buttons as $button) {
13741 $addclass = empty($button['addclass
']) ? '' : $button['addclass
'];
13742 // Add onclick to disable submit buttons (except cancel) after first click to prevent duplicate form submissions on slow connections
13743 $onclick = ($button['name'] !== 'cancel
') ? ' onclick=
"if(this.form && this.form.checkValidity && !this.form.checkValidity()) { return true; } this.disabled=true; this.form.submit();"' : '';
13744 $retstring .= '<input
type=
"submit" class=
"button marginleftonly marginrightonly button-' . $button['name'] . ($morecss ? ' ' . $morecss : '') . ' ' . $addclass . '" name=
"' . $button['name'] . '" value=
"' . dol_escape_htmltag($langs->transnoentities($button['label_key'])) . '"' . $onclick . '>
';
13746 $retstring .= $withoutdiv ? '' : '</div>
';
13748 if ($dol_openinpopup) {
13749 $retstring .= '<!-- buttons are shown into a $dol_openinpopup=
' . dol_escape_htmltag($dol_openinpopup) . ' context, so we enable the close of dialog on cancel -->
' . "\n";
13750 $retstring .= '<script nonce=
"' . getNonce() . '">
';
13751 $retstring .= 'jQuery(
".button-cancel").click(
function(e) {
13752 e.preventDefault(); console.log(\
'We click on cancel in iframe popup ' .
dol_escape_js($dol_openinpopup) .
'\');
13753 window.parent.jQuery(\
'#idfordialog' .
dol_escape_js($dol_openinpopup) .
'\').dialog(\
'close\');
13755 $retstring .=
'</script>';
13774 $num = count($this->cache_invoice_subtype);
13781 $sql =
"SELECT rowid, code, label as label";
13782 $sql .=
" FROM " . MAIN_DB_PREFIX .
'c_invoice_subtype';
13783 $sql .=
" WHERE active = 1";
13785 $resql = $this->db->query($sql);
13787 $num = $this->db->num_rows($resql);
13789 while ($i < $num) {
13790 $obj = $this->db->fetch_object($resql);
13793 $label = ($langs->trans(
"InvoiceSubtype" . $obj->rowid) !=
"InvoiceSubtype" . $obj->rowid) ? $langs->trans(
"InvoiceSubtype" . $obj->rowid) : (($obj->label !=
'-') ? $obj->label :
'');
13794 $this->cache_invoice_subtype[$obj->rowid][
'rowid'] = $obj->rowid;
13795 $this->cache_invoice_subtype[$obj->rowid][
'code'] = $obj->code;
13796 $this->cache_invoice_subtype[$obj->rowid][
'label'] = $label;
13800 $this->cache_invoice_subtype =
dol_sort_array($this->cache_invoice_subtype,
'code',
'asc', 0, 0, 1);
13804 dol_print_error($this->db);
13822 global $langs, $user;
13825 dol_syslog(__METHOD__ .
" selected=" . $selected .
", htmlname=" . $htmlname, LOG_DEBUG);
13827 $this->load_cache_invoice_subtype();
13829 $out .=
'<select id="' . $htmlname .
'" class="flat selectsubtype' . ($morecss ?
' ' . $morecss :
'') .
'" name="' . $htmlname .
'">';
13831 $out .=
'<option value="0"> </option>';
13834 foreach ($this->cache_invoice_subtype as $rowid => $subtype) {
13835 $label = $subtype[
'label'];
13836 $out .=
'<option value="' . $subtype[
'rowid'] .
'"';
13837 if ($selected == $subtype[
'rowid']) {
13838 $out .=
' selected="selected"';
13842 $out .=
'</option>';
13845 $out .=
'</select>';
13846 if ($user->admin && empty($noinfoadmin)) {
13847 $out .=
info_admin($langs->trans(
"YouCanChangeValuesForThisListFromDictionarySetup"), 1);
13868 'type' =>
'search',
13869 'name' => $htmlName,
13871 'class' =>
"search-tool-input",
13872 'placeholder' => $langs->trans(
'Search'),
13873 'autocomplete' =>
'off'
13881 if ($dataTarget !==
false) {
13882 $attr[
'data-search-tool-target'] = $dataTarget;
13886 if (!empty($params[
'attr']) && is_array($params[
'attr'])) {
13887 foreach ($params[
'attr'] as $key => $value) {
13888 if ($key ==
'class') {
13889 $attr[
'class'] .=
' '.$value;
13890 } elseif ($key ==
'classOverride') {
13891 $attr[
'class'] = $value;
13893 $attr[$key] = $value;
13899 if (!empty($attr[
'title']) && !empty($attr[
'class']) && strpos($attr[
'class'],
'classfortooltip') ===
false) {
13900 $attr[
'class'] .=
' classfortooltip';
13903 $TCompiledAttr = [];
13904 foreach ($attr as $key => $value) {
13905 if (in_array($key, [
'data-target'])
13906 || (!empty($params[
'use_unsecured_unescapedattr']) && is_array($params[
'use_unsecured_unescapedattr']) && in_array($key, $params[
'use_unsecured_unescapedattr']))) {
13909 $value = dolPrintHTMLForAttribute($value);
13912 $TCompiledAttr[] = $key .
'="' . $value .
'"';
13915 $compiledAttributes = implode(
' ', $TCompiledAttr);
13918 return '<div class="search-tool-container"><input '.$compiledAttributes.
'></div>';
13934 public function inputType($type, $name, $value =
'',
$id =
'', $morecss =
'', $moreparam =
'', $label =
'', $addInputLabel =
'')
13937 if ($label !=
'') {
13938 $out .=
'<label for="' . dolPrintHTMLForAttribute(
$id) .
'">';
13940 $out .=
'<input type="' . dolPrintHTMLForAttribute($type) .
'"';
13941 $out .=
' class="flat valignmiddle maxwidthonsmartphone ' . dolPrintHTMLForAttribute($morecss) .
'"';
13943 $out .=
' id="' . dolPrintHTMLForAttribute(
$id) .
'"';
13945 $out .=
' name="' . dolPrintHTMLForAttribute($name) .
'"';
13946 $out .=
' value="' . dolPrintHTMLForAttribute($value) .
'" ';
13947 $out .= ($moreparam ?
' ' . $moreparam :
'');
13948 $out .=
' />' . $addInputLabel;
13949 if ($label !=
'') {
13950 $out .= $label .
'</label>';
13968 public function inputSelectAjax($htmlName, $array,
$id, $ajaxUrl, $ajaxData = [], $morecss =
'minwidth75', $moreparam =
'')
13972 $(document).ready(function () {
13973 $('#" . $htmlName .
"').select2({
13975 url: '" . $ajaxUrl .
"',
13977 delay: 250, // wait 250 milliseconds before triggering the request
13978 data: function (params) {
13980 search: params.term,
13981 page: params.page || 1";
13982 if (!empty($ajaxData) && is_array($ajaxData)) {
13983 foreach ($ajaxData as $key => $value) {
13984 $out .=
", " . $key .
": '" . $value .
"'";
13996 $out .= $this->selectarray($htmlName, $array,
$id, 0, 0, 0, $moreparam, 0, 0, 0,
'', $morecss);
14010 public function inputHtml($htmlName, $value, $morecss =
'', $moreparam =
'')
14012 require_once DOL_DOCUMENT_ROOT .
'/core/class/doleditor.class.php';
14013 $doleditor =
new DolEditor($htmlName, $value,
'', 200,
'dolibarr_notes',
'In',
false,
false,
isModEnabled(
'fckeditor') &&
getDolGlobalInt(
'FCKEDITOR_ENABLE_SOCIETE'), ROWS_5,
'90%');
14015 return (
string) $doleditor->Create(1,
'',
true,
'',
'', $moreparam, $morecss);
14028 public function inputText($htmlName, $value, $morecss =
'', $moreparam =
'', $options = array())
14033 if (!empty($options)) {
14035 $out .= $this->selectarray($htmlName .
"_multiinput", $options,
'', 1, 0, 0, $moreparam, 0, 0, 0,
'',
"flat maxwidthonphone" . $morecss);
14036 $out .=
'<input id="' . $htmlName .
'_multiinputadd" type="button" class="button" value="' . $langs->trans(
"Add") .
'">';
14037 $out .=
"<script>";
14039 function handlemultiinputdisabling(htmlname){
14040 console.log("We handle the disabling of used options for "+htmlname+"_multiinput");
14041 multiinput = $("#"+htmlname+"_multiinput");
14042 multiinput.find("option").each(function(){
14043 tmpval = $("#"+htmlname).val();
14044 tmpvalarray = tmpval.split("\n");
14045 valtotest = $(this).val();
14046 if(tmpvalarray.includes(valtotest)){
14047 $(this).prop("disabled",true);
14049 if($(this).prop("disabled") == true){
14050 console.log(valtotest)
14051 $(this).prop("disabled", false);
14057 $(document).ready(function () {
14058 $("#' . $htmlName .
'_multiinputadd").on("click",function() {
14059 tmpval = $("#' . $htmlName .
'").val();
14060 tmpvalarray = tmpval.split(",");
14061 valtotest = $("#' . $htmlName .
'_multiinput").val();
14062 if(valtotest != -1 && !tmpvalarray.includes(valtotest)){
14063 console.log("We add the selected value to the text area ' . $htmlName .
'");
14065 tmpval = valtotest;
14067 tmpval = tmpval + "\n" + valtotest;
14069 $("#' . $htmlName .
'").val(tmpval);
14070 handlemultiinputdisabling("' . $htmlName .
'");
14071 $("#' . $htmlName .
'_multiinput").val(-1);
14073 console.log("We add nothing the text area ' . $htmlName .
'");
14076 $("#' . $htmlName .
'").on("change",function(){
14077 handlemultiinputdisabling("' . $htmlName .
'");
14079 handlemultiinputdisabling("' . $htmlName .
'");
14081 $out .=
"</script>";
14082 $value = str_replace(
',',
"\n", $value);
14085 require_once DOL_DOCUMENT_ROOT .
'/core/class/doleditor.class.php';
14086 $doleditor =
new DolEditor($htmlName, (
string) $value,
'', 200,
'dolibarr_notes',
'In',
false,
false,
false, ROWS_5,
'90%');
14087 $out .= (string) $doleditor->Create(1,
'',
true,
'',
'', $moreparam, $morecss);
14102 public function inputRadio($htmlName, $options, $selectedValue, $morecss =
'', $moreparam =
'')
14105 foreach ($options as $optionKey => $optionLabel) {
14106 $selected = ((string) $selectedValue) === ((string) $optionKey) ?
' checked="checked"' :
'';
14107 $optionId = $htmlName .
'_' . $optionKey;
14108 $out .=
'<input class="flat' . $morecss .
'" type="radio" name="' . $htmlName .
'" id="' . $optionId .
'" value="' . dolPrintHTMLForAttribute((
string) $optionKey) .
'"' . $selected . $moreparam .
'/><label for="' . $optionId .
'">' . $optionLabel .
'</label><br>';
14124 public function inputStars($htmlName, $size, $value, $morecss =
'', $moreparam =
'')
14126 $out =
'<input type="hidden" class="flat ' . $morecss .
'" name="' . $htmlName .
'" id="' . $htmlName .
'" value="' . dolPrintHTMLForAttribute((
string) $value) .
'"' . $moreparam .
'>';
14127 $out .=
'<div class="star-selection" id="' . $htmlName .
'_selection">';
14128 for ($i = 1; $i <= $size; $i++) {
14129 $out .=
'<span class="star" data-value="' . $i .
'">' . img_picto(
'',
'fontawesome_star_fas') .
'</span>';
14133 jQuery(function($) { /* commonobject.class.php 1 */
14134 let container = $("#' . $htmlName .
'_selection");
14135 let selectedStars = parseInt($("#' . $htmlName .
'").val()) || 0;
14136 container.find(".star").each(function() {
14137 $(this).toggleClass("active", $(this).data("value") <= selectedStars);
14139 container.find(".star").on("mouseover", function() {
14140 let selectedStar = $(this).data("value");
14141 container.find(".star").each(function() {
14142 $(this).toggleClass("active", $(this).data("value") <= selectedStar);
14145 container.on("mouseout", function() {
14146 container.find(".star").each(function() {
14147 $(this).toggleClass("active", $(this).data("value") <= selectedStars);
14150 container.find(".star").off("click").on("click", function() {
14151 selectedStars = $(this).data("value");
14152 if (selectedStars === 1 && $("#' . $htmlName .
'").val() == 1) {
14155 $("#' . $htmlName .
'").val(selectedStars);
14156 container.find(".star").each(function() {
14157 $(this).toggleClass("active", $(this).data("value") <= selectedStars);
14175 public function inputIcon($htmlName, $value, $morecss =
'', $moreparam =
'')
14184 $out =
'<input type="text" class="form-control icp icp-auto iconpicker-element iconpicker-input flat ' . $morecss .
' maxwidthonsmartphone"';
14185 $out .=
' name="' . $htmlName .
'" id="' . $htmlName .
'" value="' . dolPrintHTMLForAttribute((
string) $value) .
'" ' . ((string) $moreparam) .
'>';
14187 $out .=
'<script>';
14188 $options =
"{ title: '<b>" . $langs->trans(
"IconFieldSelector") .
"</b>', placement: 'right', showFooter: false, templates: {";
14189 $options .=
"iconpicker: '<div class=\"iconpicker\"><div style=\"background-color:#EFEFEF;\" class=\"iconpicker-items\"></div></div>',";
14190 $options .=
"iconpickerItem: '<a role=\"button\" href=\"#\" class=\"iconpicker-item\" style=\"background-color:#DDDDDD;\"><i></i></a>',";
14193 $options .=
"footer: '<div class=\"popover-footer\" style=\"background-color:#EFEFEF;\"></div>',";
14194 $options .=
"search: '<input type=\"search\" class\"form-control iconpicker-search\" placeholder=\"" . $langs->trans(
"TypeToFilter") .
"\" />',";
14195 $options .=
"popover: '<div class=\"iconpicker-popover popover\">";
14196 $options .=
" <div class=\"arrow\" ></div>";
14197 $options .=
" <div class=\"popover-title\" style=\"text-align:center;background-color:#EFEFEF;\"></div>";
14198 $options .=
" <div class=\"popover-content \" ></div>";
14199 $options .=
"</div>'}}";
14200 $out .=
"$('#" . $htmlName .
"').iconpicker(" . $options .
");";
14201 $out .=
'</script>';
14217 require_once DOL_DOCUMENT_ROOT .
'/core/class/dolgeophp.class.php';
14218 require_once DOL_DOCUMENT_ROOT .
'/core/class/geomapeditor.class.php';
14224 if (!empty($value)) {
14225 $tmparray = $dolgeophp->parseGeoString($value);
14226 $geojson = $tmparray[
'geojson'];
14227 $centroidjson = $tmparray[
'centroidjson'];
14230 return $geomapeditor->getHtml($htmlName, $geojson, $centroidjson, $type);
14242 $toPrint = array();
14243 $values = is_array($values) ? $values : array();
14245 foreach ($values as $value) {
14246 $toPrint[] =
'<li class="select2-search-choice-dolibarr noborderoncategories" style="background: #bbb">' . $value .
'</li>';
14248 if (!empty($toPrint)) {
14249 $out =
'<div class="select2-container-multi-dolibarr" style="width: 90%;"><ul class="select2-choices-dolibarr">' . implode(
' ', $toPrint) .
'</ul></div>';
14264 $out =
'<div class="star-selection" data-value="' . dolPrintHTMLForAttribute((
string) $value) .
'">';
14265 for ($i = 1; $i <= $size; $i++) {
14266 $out .=
'<span class="star' . ($i <= $value ?
' active' :
'') .
'" data-value="' . $i .
'">' . img_picto(
'',
'fontawesome_star_fas') .
'</span>';
14281 $out =
'<span class="' . dolPrintHTMLForAttribute((
string) $value) .
'"></span>';
14297 if (!empty($value)) {
14298 require_once DOL_DOCUMENT_ROOT .
'/core/class/dolgeophp.class.php';
14300 if ($type ==
'point') {
14301 $out = $dolgeophp->getXYString($value);
14303 $out = $dolgeophp->getPointString($value);
14324 public function getNomUrl(&
$object, $withpicto = 0, $option =
'', $maxlength = 0, $save_lastsearch_value = -1, $notooltip = 0, $morecss =
'', $add_label = 0, $sep =
' - ')
14326 if (is_object(
$object) && method_exists(
$object,
'getNomUrl')) {
14327 $out =
$object->getNomUrl($withpicto, $option, $maxlength, $save_lastsearch_value, $notooltip, $morecss, $add_label, $sep);
$id
Support class for third parties, contacts, members, users or resources.
if(! $sortfield) if(! $sortorder) $object
$propal type
'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',...
ajax_autocompleter($selected, $htmlname, $url, $urloption='', $minLength=2, $autoselect=0, $ajaxoptions=array(), $moreparams='')
Generic function that return javascript to add to transform a common input text or select field into ...
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='', $placeholder='')
Convert a html select field into an ajax combobox.
Class to manage bank accounts.
Class to manage members of a foundation.
Class to manage categories.
Class to manage bank accounts description of third parties.
Class to manage a WYSIWYG editor.
Class to manage Geo processing Usage: $dolgeophp=new DolGeoPHP($db);.
Class to manage ECM files.
const STATUS_OPEN_INTERNAL
Warehouse open and only operations for stock transfers/corrections allowed (not for customer shipping...
const STATUS_OPEN_ALL
Warehouse open and any operations are allowed (customer shipping, supplier dispatch,...
const STATUS_CLOSED
Warehouse closed, inactive.
Class to manage invoice templates.
Class to manage a Leaflet map width geometrics objects.
Class to parse product price expressions.
Class to manage predefined suppliers products.
Class to manage products or services.
const TYPE_PRODUCT
Regular product.
const TYPE_SERVICE
Service.
Class to manage projects.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage subscriptions of foundation members.
Class to manage translations.
Class to manage Dolibarr users.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
if(! $sortfield) if(! $sortorder) $module
getCountry($searchkey, $withcode='', $dbtouse=null, $outputlangs=null, $entconv=1, $searchlabel='')
Return country label, code or id from an id, code or label.
currency_name($code_iso, $withcode=0, $outputlangs=null)
Return label of currency or code+label.
isInEEC($object)
Return if a country of an object is inside the EEC (European Economic Community)
getServerTimeZoneInt($refgmtdate='now')
Return server timezone int.
removeGlobalParenthesis($string)
Remove first and last parenthesis but only if first is the opening and last the closing of the same g...
dol_now($mode='gmt')
Return date for now.
dol_print_email($email, $contactid=0, $socid=0, $addlink=0, $max=0, $showinvalid=2, $withpicto=0, $morecss='paddingrightonly')
Show EMail link formatted for HTML output.
dol_getIdFromCode($db, $key, $tablename, $fieldkey='code', $fieldid='id', $entityfilter=0, $filters='', $useCache=true)
Return an id or code from a code or id.
dolForgeExplodeAnd($sqlfilters)
Explode an universal search string with AND parts.
vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0, $html=0)
Return a string with VAT rate label formatted for view output Used into pdf and HTML pages.
dol_print_phone($phone, $countrycode='', $contactid=0, $socid=0, $addlink='', $separ=" ", $withpicto='', $titlealt='', $adddivfloat=0, $morecss='paddingright')
Format phone numbers according to country.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
currentToken()
Return the value of token currently saved into session with name 'token'.
dolBuildUrl($url, $params=[], $addtoken=false, $anchor='')
Return path of url.
dol_eval($s, $returnvalue=1, $hideerrors=1, $onlysimplestring='1')
Replace eval function to add more security.
dol_nl2br($stringtoencode, $nl2brmode=0, $forxml=false)
Replace CRLF in string with a HTML BR tag.
dol_print_url($url, $target='_blank', $max=32, $withpicto=0, $morecss='')
Show Url link.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
getDolUserString($key, $default='', $tmpuser=null)
Return Dolibarr user constant string value.
GETPOSTISARRAY($paramname, $method=0)
Return true if the parameter $paramname is submit from a POST OR GET as an array.
natural_search($fields, $value, $mode=0, $nofirstand=0, $sqltoadd='')
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
getElementProperties($elementType)
Get an array with properties of an element.
dol_escape_js($stringtoescape, $mode=0, $noescapebackslashn=0)
Returns text escaped for inclusion into JavaScript code.
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...
if(!function_exists( 'dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
dol_string_unaccent($str)
Clean a string from all accent characters to be used as ref, login or by dol_sanitizeFileName.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
dol_string_neverthesehtmltags($stringtoclean, $disallowed_tags=array('textarea'), $cleanalsosomestyles=0)
Clean a string from some undesirable HTML tags.
get_default_npr(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that returns whether VAT must be recoverable collected VAT (e.g.: VAT NPR in France)
dol_htmlentities($string, $flags=ENT_QUOTES|ENT_SUBSTITUTE, $encoding='UTF-8', $double_encode=false)
Replace htmlentities functions.
forgeSQLFromUniversalSearchCriteria($filter, &$errorstr='', $noand=0, $nopar=0, $noerror=0, $forbiddenfields=array())
forgeSQLFromUniversalSearchCriteria
getImageFileNameForSize($file, $extName, $extImgTarget='')
Return the filename of file to get the thumbs.
colorIsLight($stringcolor)
Return true if the color is light.
dolIsAllowedForPreview($file)
Return if a file is qualified for preview.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '...' if string larger than length.
getNonce()
Return a random string to be used as a nonce value for js.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
dol_htmlentitiesbr($stringtoencode, $nl2brmode=0, $pagecodefrom='UTF-8', $removelasteolbr=1)
This function is called to encode a string into a HTML string but differs from htmlentities because a...
dol_htmlwithnojs($stringtoencode, $nouseofiframesandbox=0, $check='restricthtml')
Sanitize a HTML to remove js, dangerous content and external links.
dol_string_onlythesehtmltags($stringtoclean, $cleanalsosomestyles=1, $removeclassattribute=1, $cleanalsojavascript=0, $allowiframe=0, $allowed_tags=array(), $allowlink=0, $allowscript=0, $allowstyle=0, $allowphp=0)
Clean a string to keep only desirable HTML tags.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_sanitizeKeyCode($str)
Clean a string to use it as a key or code.
isModEnabled($module)
Is Dolibarr module enabled.
array_merge_recursive_distinct(array $array1, array $array2)
Recursively merges two arrays while preserving keys and replacing existing values.
get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that return vat rate of a product line (according to seller, buyer and product vat rate) VAT...
get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart='')
Return a path to have a the directory according to object where files are stored.
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.
dol_nboflines_bis($text, $maxlinesize=0, $charset='UTF-8')
Return nb of lines of a formatted text with and (WARNING: string must not have mixed and br sep...
multi select button
0 = Do not include form tag and submit button -1 = Do not include form tag but include submit button
treeview li table
No Email.
picto_from_langcode($codelang, $moreatt='', $notitlealt=0)
Return img flag of country for a language code or country code.
commonHtmlAttributeBuilder($attr, array $unescapedAttr=[])
Builds an array of safe and properly escaped HTML attributes from a key-value pair list.
dolButtonToOpenUrlInDialogPopup($name, $label, $buttonstring, $url, $disabled='', $morecss='classlink button bordertransp', $jsonopen='', $jsonclose='', $accesskey='')
Return HTML code to output a button to open a dialog popup box.
showDimensionInBestUnit($dimension, $unit, $type, $outputlangs, $round=-1, $forceunitoutput='no', $use_short_label=0)
Output a dimension with best unit.
getAdvancedPreviewUrl($modulepart, $relativepath, $alldata=0, $param='')
Return URL we can use for advanced preview links.
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='', $textonpictotooltip='', $cssfordropdown='info_admin')
Show information in HTML for admin users or standard users.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Class to generate the form for creating a new ticket.
dol_get_trunk_prefix($db, $phone_code)
Get the national trunk prefix for a phone code.
dol_parse_phone($phone)
Parse a stored phone number into country code and number parts.
dol_get_phone_code_from_country($db, $country_id)
Get the phone calling code for a country.
measuringUnitString($unitid, $measuring_style='', $unitscale=null, $use_short_label=0, $outputlangs=null)
Return translation label of a unit key.
$conf db user
Active Directory does not allow anonymous connections.
$conf db name
Only used if Module[ID]Name translation string is not found.
getMaxFileSizeArray()
Return the max allowed for file upload.
dol_hash($chain, $type='0', $nosalt=0, $mode=0)
Returns a hash (non reversible encryption) of a string.
dolDecrypt($chain, $key='', $patterntotest='')
Decode a string with a symmetric encryption.
testSqlAndScriptInject($val, $type)
Security: WAF layer for SQL Injection and XSS Injection (scripts) protection (Filters on GET,...