PageRenderTime 58ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/htdocs/core/class/html.form.class.php

https://bitbucket.org/speedealing/speedealing
PHP | 3267 lines | 1799 code | 306 blank | 1162 comment | 600 complexity | 82c19266cd83ba69aa57d06d8ea0ab60 MD5 | raw file
Possible License(s): LGPL-3.0, LGPL-2.1, GPL-3.0, MIT

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /* Copyright (c) 2002-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  3. * Copyright (C) 2004-2012 Laurent Destailleur <eldy@users.sourceforge.net>
  4. * Copyright (C) 2004 Benoit Mortier <benoit.mortier@opensides.be>
  5. * Copyright (C) 2004 Sebastien Di Cintio <sdicintio@ressource-toi.org>
  6. * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
  7. * Copyright (C) 2005-2013 Regis Houssin <regis.houssin@capnetworks.com>
  8. * Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr>
  9. * Copyright (C) 2006 Marc Barilley/Ocebo <marc@ocebo.com>
  10. * Copyright (C) 2007 Franky Van Liedekerke <franky.van.liedekerker@telenet.be>
  11. * Copyright (C) 2007 Patrick Raguin <patrick.raguin@gmail.com>
  12. * Copyright (C) 2010 Juanjo Menent <jmenent@2byte.es>
  13. * Copyright (C) 2010 Philippe Grand <philippe.grand@atoo-net.com>
  14. * Copyright (C) 2011-2012 Herve Prot <herve.prot@symeos.com>
  15. * Copyright (C) 2012 Marcos GarcĂ­a <marcosgdf@gmail.com>
  16. *
  17. * This program is free software; you can redistribute it and/or modify
  18. * it under the terms of the GNU General Public License as published by
  19. * the Free Software Foundation; either version 3 of the License, or
  20. * (at your option) any later version.
  21. *
  22. * This program is distributed in the hope that it will be useful,
  23. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25. * GNU General Public License for more details.
  26. *
  27. * You should have received a copy of the GNU General Public License
  28. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  29. */
  30. /**
  31. * \file htdocs/core/class/html.form.class.php
  32. * \ingroup core
  33. * \brief File of class with all html predefined components
  34. */
  35. /**
  36. * Class to manage generation of HTML components
  37. * Only common components must be here.
  38. */
  39. class Form {
  40. var $db;
  41. var $error;
  42. var $num;
  43. // Cache arrays
  44. var $cache_types_paiements = array();
  45. var $cache_conditions_paiements = array();
  46. var $cache_availability = array();
  47. var $cache_demand_reason = array();
  48. var $cache_types_fees = array();
  49. var $cache_currencies = array();
  50. var $cache_vatrates = array();
  51. var $tva_taux_value;
  52. var $tva_taux_libelle;
  53. /**
  54. * Constructor
  55. */
  56. public function __construct($db = '') {
  57. $this->db = $db;
  58. }
  59. /**
  60. * Output key field for an editable field
  61. *
  62. * @param string $text Text of label or key to translate
  63. * @param string $htmlname Name of select field
  64. * @param string $preselected Name of Value to show/edit (not used in this function)
  65. * @param object $object Object
  66. * @param boolean $perm Permission to allow button to edit parameter
  67. * @param string $typeofdata Type of data ('string' by default, 'email', 'numeric:99', 'text' or 'textarea:rows:cols', 'day' or 'datepicker', 'ckeditor:dolibarr_zzz:width:height:savemethod:1:rows:cols', 'select:xxx'...)
  68. * @param string $moreparam More param to add on a href URL
  69. * @return string HTML edit field
  70. */
  71. function editfieldkey($text, $htmlname, $preselected, $object, $perm, $typeofdata = 'string', $moreparam = '') {
  72. global $conf, $langs;
  73. $ret = '';
  74. // TODO change for compatibility
  75. if (!preg_match('/^select;/', $typeofdata)) {
  76. if ($perm) {
  77. $tmp = explode(':', $typeofdata);
  78. $ret.= '<div class="editkey_' . $tmp[0] . (!empty($tmp[1]) ? ' ' . $tmp[1] : '') . '" id="' . $htmlname . '">';
  79. $ret.= $langs->trans($text);
  80. $ret.= '</div>' . "\n";
  81. } else {
  82. $ret.= $langs->trans($text);
  83. }
  84. } else {
  85. $ret.='<table class="nobordernopadding" width="100%"><tr><td nowrap="nowrap">';
  86. $ret.=$langs->trans($text);
  87. $ret.='</td>';
  88. if (GETPOST('action') != 'edit' . $htmlname && $perm)
  89. $ret.='<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=edit' . $htmlname . '&amp;id=' . $object->id . $moreparam . '">' . img_edit($langs->trans('Edit'), 1) . '</a></td>';
  90. $ret.='</tr></table>';
  91. }
  92. return $ret;
  93. }
  94. /**
  95. * Output val field for an editable field
  96. *
  97. * @param string $text Text of label (not used in this function)
  98. * @param string $htmlname Name of select field
  99. * @param string $value Value to show/edit
  100. * @param object $object Object
  101. * @param boolean $perm Permission to allow button to edit parameter
  102. * @param string $typeofdata Type of data ('string' by default, 'email', 'numeric:99', 'text' or 'textarea:rows:cols', 'day' or 'datepicker', 'ckeditor:dolibarr_zzz:width:height:savemethod:toolbarstartexpanded:rows:cols', 'select:xxx'...)
  103. * @param string $editvalue When in edit mode, use this value as $value instead of value
  104. * @param object $extObject External object
  105. * @param string $success Success message
  106. * @param string $moreparam More param to add on a href URL
  107. * @return string HTML edit field
  108. */
  109. function editfieldval($text, $htmlname, $value, $object, $perm, $typeofdata = 'string', $editvalue = '', $extObject = null, $success = null, $moreparam = '') {
  110. global $conf, $langs, $db;
  111. $ret = '';
  112. // When option to edit inline is activated
  113. $ret.=$this->editInPlace($object, $value, $htmlname, $perm, $typeofdata, $editvalue, $extObject, $success);
  114. return $ret;
  115. }
  116. /**
  117. * Output edit in place form
  118. *
  119. * @param object $object Object
  120. * @param string $value Value to show/edit
  121. * @param string $htmlname DIV ID (field name)
  122. * @param int $condition Condition to edit
  123. * @param string $inputType Type of input ('numeric', 'datepicker', 'textarea:rows:cols', 'ckeditor:dolibarr_zzz:width:height:?:1:rows:cols', 'select:xxx')
  124. * @param string $editvalue When in edit mode, use this value as $value instead of value
  125. * @param object $extObject External object
  126. * @param string $success Success message
  127. * @return string HTML edit in place
  128. */
  129. private function editInPlace($object, $value, $htmlname, $condition, $inputType = 'text', $editvalue = null, $extObject = null, $success = null) {
  130. global $conf;
  131. $out = '';
  132. // Check parameters
  133. if (preg_match('/^text/', $inputType))
  134. $value = dol_nl2br($value);
  135. else if (preg_match('/^numeric/', $inputType))
  136. $value = price($value);
  137. else if ($inputType == 'datepicker')
  138. $value = dol_print_date($value, 'day');
  139. if ($condition) {
  140. $element = false;
  141. $table_element = false;
  142. $fk_element = false;
  143. $loadmethod = false;
  144. $savemethod = false;
  145. $ext_element = false;
  146. $button_only = true;
  147. if (is_object($object)) {
  148. $element = $object->element;
  149. $table_element = $object->table_element;
  150. $fk_element = $object->id;
  151. }
  152. if (is_object($extObject)) {
  153. $ext_element = $extObject->element;
  154. }
  155. if (preg_match('/^(string|email|numeric)/', $inputType)) {
  156. $tmp = explode(':', $inputType);
  157. $inputType = $tmp[0];
  158. if (!empty($tmp[1]))
  159. $inputOption = $tmp[1];
  160. if (!empty($tmp[2]))
  161. $savemethod = $tmp[2];
  162. }
  163. else if (preg_match('/^datepicker/', $inputType)) {
  164. $tmp = explode(':', $inputType);
  165. $inputType = $tmp[0];
  166. if (!empty($tmp[1]))
  167. $inputOption = $tmp[1];
  168. if (!empty($tmp[2]))
  169. $savemethod = $tmp[2];
  170. $out.= '<input id="timestamp" type="hidden"/>' . "\n"; // Use for timestamp format
  171. }
  172. else if (preg_match('/^(select|autocomplete)/', $inputType)) {
  173. $tmp = explode(':', $inputType);
  174. $inputType = $tmp[0];
  175. $loadmethod = $tmp[1];
  176. if (!empty($tmp[2]))
  177. $savemethod = $tmp[2];
  178. if (!empty($tmp[3]))
  179. $button_only = true;
  180. }
  181. else if (preg_match('/^text/', $inputType)) {
  182. $tmp = explode(':', $inputType);
  183. $inputType = $tmp[0];
  184. if (!empty($tmp[1]))
  185. $rows = $tmp[1];
  186. if (!empty($tmp[2]))
  187. $cols = $tmp[2];
  188. }
  189. else if (preg_match('/^ckeditor/', $inputType)) {
  190. $tmp = explode(':', $inputType);
  191. $inputType = $tmp[0];
  192. $toolbar = $tmp[1];
  193. if (!empty($tmp[2]))
  194. $width = $tmp[2];
  195. if (!empty($tmp[3]))
  196. $heigth = $tmp[3];
  197. if (!empty($tmp[4]))
  198. $savemethod = $tmp[4];
  199. $out.= '<input id="ckeditor_toolbar" value="' . $toolbar . '" type="hidden"/>' . "\n";
  200. }
  201. $out.= '<input id="element_id_' . $htmlname . '" type="hidden" value="' . $object->id . '"/>';
  202. $out.= '<input id="element_class_' . $htmlname . '" type="hidden" value="' . get_class($object) . '"/>';
  203. if (!empty($loadmethod))
  204. $out.= '<input id="loadmethod_' . $htmlname . '" value="' . $loadmethod . '" type="hidden"/>' . "\n";
  205. if (!empty($savemethod))
  206. $out.= '<input id="savemethod_' . $htmlname . '" value="' . $savemethod . '" type="hidden"/>' . "\n";
  207. if (!empty($ext_element))
  208. $out.= '<input id="ext_element_' . $htmlname . '" value="' . $ext_element . '" type="hidden"/>' . "\n";
  209. if (!empty($success))
  210. $out.= '<input id="success_' . $htmlname . '" value="' . $success . '" type="hidden"/>' . "\n";
  211. $out.= '<span id="viewval_' . $htmlname . '" class="viewval_' . $inputType . ($button_only ? ' inactive' : ' active') . '">';
  212. $out.= $object->print_fk_extrafields($htmlname);
  213. $out.= '</span>' . "\n";
  214. if (preg_match('/^tag/', $inputType)) {
  215. $out.= '<ul class="array_tag_handler" id="editval_' . $htmlname . '"></ul>';
  216. } else {
  217. $out.= '<span id="editval_' . $htmlname . '" class="editval_' . $inputType . ($button_only ? ' inactive' : ' active') . ' hideobject">';
  218. $out.= (!empty($editvalue) ? $editvalue : $value);
  219. $out.= '</span>' . "\n";
  220. }
  221. } else {
  222. if (preg_match('/^tag/', $inputType)) {
  223. $out.= $object->LibTag($value, array("key" => $htmlname));
  224. } else {
  225. $out.= $object->print_fk_extrafields($htmlname);
  226. }
  227. }
  228. return $out;
  229. }
  230. /**
  231. * Show a text and picto with tooltip on text or picto
  232. *
  233. * @param string $text Text to show
  234. * @param string $htmltext Content html of tooltip. Must be HTML/UTF8 encoded.
  235. * @param int $tooltipon 1=tooltip sur texte, 2=tooltip sur picto, 3=tooltip sur les 2
  236. * @param int $direction -1=Le picto est avant, 0=pas de picto, 1=le picto est apres
  237. * @param string $img Code img du picto (use img_xxx() function to get it)
  238. * @param string $extracss Add a CSS style to td tags
  239. * @param int $notabs 0=Include table and tr tags, 1=Do not include table and tr tags, 2=use div, 3=use span
  240. * @param string $incbefore Include code before the text
  241. * @param int $noencodehtmltext Do not encode into html entity the htmltext
  242. * @return string Code html du tooltip (texte+picto)
  243. * @see Use function textwithpicto if you can.
  244. */
  245. function textwithtooltip($text, $htmltext, $tooltipon = 1, $direction = 0, $img = '', $extracss = '', $notabs = 0, $incbefore = '', $noencodehtmltext = 0) {
  246. global $conf;
  247. if ($incbefore)
  248. $text = $incbefore . $text;
  249. if (!$htmltext)
  250. return $text;
  251. $tag = 'td';
  252. if ($notabs == 2)
  253. $tag = 'div';
  254. if ($notabs == 3)
  255. $tag = 'span';
  256. // Sanitize tooltip
  257. $htmltext = str_replace("\\", "\\\\", $htmltext);
  258. $htmltext = str_replace("\r", "", $htmltext);
  259. $htmltext = str_replace("\n", "", $htmltext);
  260. $htmltext = str_replace('"', "&quot;", $htmltext);
  261. if ($tooltipon == 2 || $tooltipon == 3)
  262. $paramfortooltipimg = ' class="classfortooltip' . ($extracss ? ' ' . $extracss : '') . '" title="' . ($noencodehtmltext ? $htmltext : dol_escape_htmltag($htmltext, 1)) . '"'; // Attribut to put on td img tag to store tooltip
  263. else
  264. $paramfortooltipimg = ($extracss ? ' class="' . $extracss . '"' : ''); // Attribut to put on td text tag
  265. if ($tooltipon == 1 || $tooltipon == 3)
  266. $paramfortooltiptd = ' class="classfortooltip' . ($extracss ? ' ' . $extracss : '') . '" title="' . ($noencodehtmltext ? $htmltext : dol_escape_htmltag($htmltext, 1)) . '"'; // Attribut to put on td tag to store tooltip
  267. else
  268. $paramfortooltiptd = ($extracss ? ' class="' . $extracss . '"' : ''); // Attribut to put on td text tag
  269. $s = "";
  270. if (empty($notabs))
  271. $s.='<table class="nobordernopadding" summary=""><tr>';
  272. if ($direction < 0)
  273. $s.='<' . $tag . $paramfortooltipimg . ' valign="top" width="14">' . $img . '</' . $tag . '>';
  274. if ($text != '')
  275. $s.='<' . $tag . $paramfortooltiptd . '>' . (($direction < 0) ? '&nbsp;' : '') . $text . (($direction > 0) ? '&nbsp;' : '') . '</' . $tag . '>';
  276. if ($direction > 0)
  277. $s.='<' . $tag . $paramfortooltipimg . ' valign="top" width="14">' . $img . '</' . $tag . '>';
  278. if (empty($notabs))
  279. $s.='</tr></table>';
  280. return $s;
  281. }
  282. /**
  283. * Show a text with a picto and a tooltip on picto
  284. *
  285. * @param string $text Text to show
  286. * @param string $htmltext Content of tooltip
  287. * @param int $direction 1=Icon is after text, -1=Icon is before text, 0=no icon
  288. * @param string $type Type of picto (info, help, warning, superadmin...)
  289. * @param string $extracss Add a CSS style to td tags
  290. * @param int $noencodehtmltext Do not encode into html entity the htmltext
  291. * @param int $notabs 0=Include table and tr tags, 1=Do not include table and tr tags, 2=use div, 3=use span
  292. * @return string HTML code of text, picto, tooltip
  293. */
  294. function textwithpicto($text, $htmltext, $direction = 1, $type = 'help', $extracss = '', $noencodehtmltext = 0, $notabs = 0) {
  295. global $conf;
  296. $alt = '';
  297. //For backwards compatibility
  298. if ($type == '0')
  299. $type = 'info';
  300. elseif ($type == '1')
  301. $type = 'help';
  302. // If info or help with no javascript, show only text
  303. if (empty($conf->use_javascript_ajax)) {
  304. if ($type == 'info' || $type == 'help')
  305. return $text;
  306. else {
  307. $alt = $htmltext;
  308. $htmltext = '';
  309. }
  310. }
  311. // If info or help with smartphone, show only text
  312. if (!empty($conf->browser->phone)) {
  313. if ($type == 'info' || $type == 'help')
  314. return $text;
  315. }
  316. if ($type == 'info')
  317. $img = img_help(0, $alt);
  318. elseif ($type == 'help')
  319. $img = img_help(1, $alt);
  320. elseif ($type == 'superadmin')
  321. $img = img_picto($alt, 'redstar');
  322. elseif ($type == 'admin')
  323. $img = img_picto($alt, 'star');
  324. elseif ($type == 'warning')
  325. $img = img_warning($alt);
  326. return $this->textwithtooltip($text, $htmltext, 2, $direction, $img, $extracss, $notabs, '', $noencodehtmltext);
  327. }
  328. /**
  329. * Return list of types of lines (product or service)
  330. * Example: 0=product, 1=service, 9=other (for external module)
  331. *
  332. * @param string $selected Preselected type
  333. * @param string $htmlname Name of field in html form
  334. * @param int $showempty Add an empty field
  335. * @param int $hidetext Do not show label before combo box
  336. * @param string $forceall Force to show products and services in combo list, whatever are activated modules
  337. * @return void
  338. */
  339. function select_type_of_lines($selected = '', $htmlname = 'type', $showempty = 0, $hidetext = 0, $forceall = 0) {
  340. global $db, $langs, $user, $conf;
  341. // If product & services are enabled or both disabled.
  342. if ($forceall || (!empty($conf->product->enabled) && !empty($conf->service->enabled))
  343. || (empty($conf->product->enabled) && empty($conf->service->enabled))) {
  344. if (empty($hidetext))
  345. print $langs->trans("Type") . ': ';
  346. print '<select class="flat" id="select_' . $htmlname . '" name="' . $htmlname . '">';
  347. if ($showempty) {
  348. print '<option value="-1"';
  349. if ($selected == -1)
  350. print ' selected="selected"';
  351. print '>&nbsp;</option>';
  352. }
  353. print '<option value="0"';
  354. if (0 == $selected)
  355. print ' selected="selected"';
  356. print '>' . $langs->trans("Product");
  357. print '<option value="1"';
  358. if (1 == $selected)
  359. print ' selected="selected"';
  360. print '>' . $langs->trans("Service");
  361. print '</select>';
  362. //if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionnarySetup"),1);
  363. }
  364. if (!$forceall && empty($conf->product->enabled) && !empty($conf->service->enabled)) {
  365. print '<input type="hidden" name="' . $htmlname . '" value="1">';
  366. }
  367. if (!$forceall && !empty($conf->product->enabled) && empty($conf->service->enabled)) {
  368. print '<input type="hidden" name="' . $htmlname . '" value="0">';
  369. }
  370. }
  371. /**
  372. * Load into cache cache_types_fees, array of types of fees
  373. *
  374. * @return int Nb of lines loaded, 0 if already loaded, <0 if ko
  375. * TODO move in DAO class
  376. */
  377. function load_cache_types_fees() {
  378. return false;
  379. /*
  380. global $langs;
  381. $langs->load("trips");
  382. if (count($this->cache_types_fees))
  383. return 0; // Cache already load
  384. $sql = "SELECT c.code, c.libelle as label";
  385. $sql.= " FROM " . MAIN_DB_PREFIX . "c_type_fees as c";
  386. $sql.= " ORDER BY lower(c.libelle) ASC";
  387. dol_syslog(get_class($this) . '::load_cache_types_fees sql=' . $sql, LOG_DEBUG);
  388. $resql = $this->db->query($sql);
  389. if ($resql) {
  390. $num = $this->db->num_rows($resql);
  391. $i = 0;
  392. while ($i < $num) {
  393. $obj = $this->db->fetch_object($resql);
  394. // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut
  395. $label = ($obj->code != $langs->trans($obj->code) ? $langs->trans($obj->code) : $langs->trans($obj->label));
  396. $this->cache_types_fees[$obj->code] = $label;
  397. $i++;
  398. }
  399. return $num;
  400. } else {
  401. dol_print_error($this->db);
  402. return -1;
  403. }
  404. */
  405. }
  406. /**
  407. * Return list of types of notes
  408. *
  409. * @param string $selected Preselected type
  410. * @param string $htmlname Name of field in form
  411. * @param int $showempty Add an empty field
  412. * @return void
  413. */
  414. function select_type_fees($selected = '', $htmlname = 'type', $showempty = 0) {
  415. global $user, $langs;
  416. dol_syslog(get_class($this) . "::select_type_fees " . $selected . ", " . $htmlname, LOG_DEBUG);
  417. $this->load_cache_types_fees();
  418. print '<select class="flat" name="' . $htmlname . '">';
  419. if ($showempty) {
  420. print '<option value="-1"';
  421. if ($selected == -1)
  422. print ' selected="selected"';
  423. print '>&nbsp;</option>';
  424. }
  425. foreach ($this->cache_types_fees as $key => $value) {
  426. print '<option value="' . $key . '"';
  427. if ($key == $selected)
  428. print ' selected="selected"';
  429. print '>';
  430. print $value;
  431. print '</option>';
  432. }
  433. print '</select>';
  434. if ($user->admin)
  435. print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionnarySetup"), 1);
  436. }
  437. /**
  438. * Output html form to select a third party
  439. *
  440. * @param string $selected Preselected type
  441. * @param string $htmlname Name of field in form
  442. * @param string $filter Optionnal filters criteras
  443. * @param int $showempty Add an empty field
  444. * @param int $showtype Show third party type in combolist (customer, prospect or supplier)
  445. * @param int $forcecombo Force to use combo box
  446. * @param array $event Event options
  447. * @return string HTML string with
  448. */
  449. function select_company($selected = '', $htmlname = 'socid', $filter = '', $showempty = 0, $showtype = 0, $forcecombo = 0, $event = array()) {
  450. global $conf, $user, $langs;
  451. $out = '';
  452. $object = new Societe($this->db);
  453. try {
  454. $result = $object->getView("list");
  455. } catch (Exception $e) {
  456. $this->error = "Fetch : Something weird happened: " . $e->getMessage() . " (errcode=" . $e->getCode() . ")\n";
  457. dol_print_error($this->db, $this->error);
  458. return 0;
  459. }
  460. $out.= '<select id="' . $htmlname . '" class="flat" name="' . $htmlname . '">';
  461. if ($showempty)
  462. $out.= '<option value="0"></option>';
  463. if (count($result->rows) > 0) {
  464. foreach ($result->rows as $aRow) {
  465. $obj = $aRow->value;
  466. $label = $obj->name;
  467. if ($showtype) {
  468. if ($obj->client || $obj->fournisseur)
  469. $label.=' (';
  470. if ($obj->client == 1 || $obj->client == 3)
  471. $label.=$langs->trans("Customer");
  472. if ($obj->client == 2 || $obj->client == 3)
  473. $label.=($obj->client == 3 ? ', ' : '') . $langs->trans("Prospect");
  474. if ($obj->fournisseur)
  475. $label.=($obj->client ? ', ' : '') . $langs->trans("Supplier");
  476. if ($obj->client || $obj->fournisseur)
  477. $label.=')';
  478. }
  479. if ($selected > 0 && $selected == $obj->_id) {
  480. $out.= '<option value="' . $obj->_id . '" selected="selected">' . $label . '</option>';
  481. } else {
  482. $out.= '<option value="' . $obj->_id . '">' . $label . '</option>';
  483. }
  484. $i++;
  485. }
  486. }
  487. $out.= '</select>';
  488. return $out;
  489. }
  490. /**
  491. * Return HTML combo list of absolute discounts
  492. *
  493. * @param string $selected Id remise fixe pre-selectionnee
  494. * @param string $htmlname Nom champ formulaire
  495. * @param string $filter Criteres optionnels de filtre
  496. * @param int $socid Id of thirdparty
  497. * @param int $maxvalue Max value for lines that can be selected
  498. * @return int Return number of qualifed lines in list
  499. */
  500. function select_remises($selected, $htmlname, $filter, $socid, $maxvalue = 0) {
  501. global $langs, $conf, $db;
  502. $discount = new DiscountAbsolute($db);
  503. $result = $discount->getView('listAvailableDiscountsPerSociete', array('key' => $socid));
  504. // On recherche les remises
  505. // $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,";
  506. // $sql.= " re.description, re.fk_facture_source";
  507. // $sql.= " FROM " . MAIN_DB_PREFIX . "societe_remise_except as re";
  508. // $sql.= " WHERE fk_soc = " . $socid;
  509. // if ($filter)
  510. // $sql.= " AND " . $filter;
  511. // $sql.= " ORDER BY re.description ASC";
  512. //
  513. // dol_syslog(get_class($this) . "::select_remises sql=" . $sql);
  514. // $resql = $this->db->query($sql);
  515. if (true) {
  516. print '<select class="flat" name="' . $htmlname . '">';
  517. $num = count($result->rows); //$this->db->num_rows($resql);
  518. $qualifiedlines = $num;
  519. $i = 0;
  520. if ($num) {
  521. print '<option value="0">&nbsp;</option>';
  522. while ($i < $num) {
  523. $obj = new DiscountAbsolute($this->db); //$this->db->fetch_object($resql);
  524. $obj->fetch($result->rows[$i]->id);
  525. $desc = dol_trunc($obj->description, 40);
  526. if ($desc == '(CREDIT_NOTE)')
  527. $desc = $langs->trans("CreditNote");
  528. if ($desc == '(DEPOSIT)')
  529. $desc = $langs->trans("Deposit");
  530. $selectstring = '';
  531. if ($selected > 0 && $selected == $obj->rowid)
  532. $selectstring = ' selected="selected"';
  533. $disabled = '';
  534. if ($maxvalue > 0 && $obj->amount_ttc > $maxvalue) {
  535. $qualifiedlines--;
  536. $disabled = ' disabled="disabled"';
  537. }
  538. print '<option value="' . $obj->id . '"' . $selectstring . $disabled . '>' . $desc . ' (' . price($obj->amount_ht) . ' ' . $langs->trans("HT") . ' - ' . price($obj->amount_ttc) . ' ' . $langs->trans("TTC") . ')</option>';
  539. $i++;
  540. }
  541. }
  542. print '</select>';
  543. return $qualifiedlines;
  544. } else {
  545. dol_print_error($this->db);
  546. return -1;
  547. }
  548. }
  549. /**
  550. * Return list of all contacts (for a third party or all)
  551. *
  552. * @param int $socid Id ot third party or 0 for all
  553. * @param string $selected Id contact pre-selectionne
  554. * @param string $htmlname Name of HTML field ('none' for a not editable field)
  555. * @param int $showempty 0=no empty value, 1=add an empty value
  556. * @param string $exclude List of contacts id to exclude
  557. * @param string $limitto Disable answers that are not id in this array list
  558. * @param string $showfunction Add function into label
  559. * @param string $moreclass Add more class to class style
  560. * @param string $showsoc Add company into label
  561. * @return int <0 if KO, Nb of contact in list if OK
  562. */
  563. function select_contacts($socid, $selected = '', $htmlname = 'contactid', $showempty = 0, $exclude = '', $limitto = '', $showfunction = 0, $moreclass = '', $showsoc = 0) {
  564. print $this->selectcontacts($socid, $selected, $htmlname, $showempty, $exclude, $limitto, $showfunction, $moreclass, $showsoc);
  565. return $this->num;
  566. }
  567. /**
  568. * Return list of all contacts (for a third party or all)
  569. *
  570. * @param int $socid Id ot third party or 0 for all
  571. * @param string $selected Id contact pre-selectionne
  572. * @param string $htmlname Name of HTML field ('none' for a not editable field)
  573. * @param int $showempty 0=no empty value, 1=add an empty value
  574. * @param string $exclude List of contacts id to exclude
  575. * @param string $limitto Disable answers that are not id in this array list
  576. * @param string $showfunction Add function into label
  577. * @param string $moreclass Add more class to class style
  578. * @param bool $options_only Return options only (for ajax treatment)
  579. * @param string $showsoc Add company into label
  580. * @return int <0 if KO, Nb of contact in list if OK
  581. */
  582. function selectcontacts($socid, $selected = '', $htmlname = 'contactid', $showempty = 0, $exclude = '', $limitto = '', $showfunction = 0, $moreclass = '', $options_only = false, $showsoc = 0) {
  583. return false;
  584. /*
  585. global $conf, $langs;
  586. $langs->load('companies');
  587. $out = '';
  588. // On recherche les societes
  589. $sql = "SELECT sp.rowid, sp.name as name, sp.firstname, sp.poste";
  590. if ($showsoc > 0) {
  591. $sql.= " , s.nom as company";
  592. }
  593. $sql.= " FROM " . MAIN_DB_PREFIX . "socpeople as sp";
  594. if ($showsoc > 0) {
  595. $sql.= " LEFT OUTER JOIN " . MAIN_DB_PREFIX . "societe as s ON s.rowid=sp.fk_soc ";
  596. }
  597. $sql.= " WHERE sp.entity IN (" . getEntity('societe', 1) . ")";
  598. if ($socid > 0)
  599. $sql.= " AND sp.fk_soc=" . $socid;
  600. $sql.= " ORDER BY sp.name ASC";
  601. dol_syslog(get_class($this) . "::select_contacts sql=" . $sql);
  602. $resql = $this->db->query($sql);
  603. if ($resql) {
  604. $num = $this->db->num_rows($resql);
  605. if ($htmlname != 'none' || $options_only)
  606. $out.= '<select class="flat' . ($moreclass ? ' ' . $moreclass : '') . '" id="' . $htmlname . '" name="' . $htmlname . '">';
  607. if ($showempty)
  608. $out.= '<option value="0"></option>';
  609. $num = $this->db->num_rows($resql);
  610. $i = 0;
  611. if ($num) {
  612. include_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php';
  613. $contactstatic = new Contact($this->db);
  614. while ($i < $num) {
  615. $obj = $this->db->fetch_object($resql);
  616. $contactstatic->id = $obj->rowid;
  617. $contactstatic->name = $obj->name;
  618. $contactstatic->lastname = $obj->name;
  619. $contactstatic->firstname = $obj->firstname;
  620. if ($htmlname != 'none') {
  621. $disabled = 0;
  622. if (is_array($exclude) && count($exclude) && in_array($obj->rowid, $exclude))
  623. $disabled = 1;
  624. if (is_array($limitto) && count($limitto) && !in_array($obj->rowid, $limitto))
  625. $disabled = 1;
  626. if ($selected && $selected == $obj->rowid) {
  627. $out.= '<option value="' . $obj->rowid . '"';
  628. if ($disabled)
  629. $out.= ' disabled="disabled"';
  630. $out.= ' selected="selected">';
  631. $out.= $contactstatic->getFullName($langs);
  632. if ($showfunction && $obj->poste)
  633. $out.= ' (' . $obj->poste . ')';
  634. if (($showsoc > 0) && $obj->company)
  635. $out.= ' - (' . $obj->company . ')';
  636. $out.= '</option>';
  637. }
  638. else {
  639. $out.= '<option value="' . $obj->rowid . '"';
  640. if ($disabled)
  641. $out.= ' disabled="disabled"';
  642. $out.= '>';
  643. $out.= $contactstatic->getFullName($langs);
  644. if ($showfunction && $obj->poste)
  645. $out.= ' (' . $obj->poste . ')';
  646. if (($showsoc > 0) && $obj->company)
  647. $out.= ' - (' . $obj->company . ')';
  648. $out.= '</option>';
  649. }
  650. }
  651. else {
  652. if ($selected == $obj->rowid) {
  653. $out.= $contactstatic->getFullName($langs);
  654. if ($showfunction && $obj->poste)
  655. $out.= ' (' . $obj->poste . ')';
  656. if (($showsoc > 0) && $obj->company)
  657. $out.= ' - (' . $obj->company . ')';
  658. }
  659. }
  660. $i++;
  661. }
  662. }
  663. else {
  664. $out.= '<option value="-1" selected="selected" disabled="disabled">' . $langs->trans("NoContactDefined") . '</option>';
  665. }
  666. if ($htmlname != 'none' || $options_only) {
  667. $out.= '</select>';
  668. }
  669. $this->num = $num;
  670. return $out;
  671. } else {
  672. dol_print_error($this->db);
  673. return -1;
  674. }
  675. */
  676. }
  677. /**
  678. * Return list of products for customer in Ajax if Ajax activated or go to select_produits_do
  679. *
  680. * @param int $selected Preselected products
  681. * @param string $htmlname Name of HTML seletc field (must be unique in page)
  682. * @param int $filtertype Filter on product type (''=nofilter, 0=product, 1=service)
  683. * @param int $limit Limit on number of returned lines
  684. * @param int $price_level Level of price to show
  685. * @param int $status -1=Return all products, 0=Products not on sell, 1=Products on sell
  686. * @param int $finished 2=all, 1=finished, 0=raw material
  687. * @param string $selected_input_value Value of preselected input text (with ajax)
  688. * @param int $hidelabel Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after)
  689. * @param array $ajaxoptions Options for ajax_autocompleter
  690. * @return void
  691. */
  692. function select_produits($selected = '', $htmlname = 'productid', $filtertype = '', $limit = 20, $price_level = 0, $status = 1, $finished = 2, $selected_input_value = '', $hidelabel = 0, $ajaxoptions = array()) {
  693. global $langs, $conf;
  694. $price_level = (!empty($price_level) ? $price_level : 0);
  695. if (!empty($conf->use_javascript_ajax) && !empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT)) {
  696. $placeholder = '';
  697. if ($selected && empty($selected_input_value)) {
  698. require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
  699. $product = new Product($this->db);
  700. $product->fetch($selected);
  701. $selected_input_value = $product->ref;
  702. }
  703. // mode=1 means customers products
  704. $urloption = 'htmlname=' . $htmlname . '&outjson=1&price_level=' . $price_level . '&type=' . $filtertype . '&mode=1&status=' . $status . '&finished=' . $finished;
  705. print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT . '/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions);
  706. if (empty($hidelabel))
  707. print $langs->trans("RefOrLabel") . ' : ';
  708. else if ($hidelabel > 1) {
  709. if (!empty($conf->global->MAIN_HTML5_PLACEHOLDER))
  710. $placeholder = ' placeholder="' . $langs->trans("RefOrLabel") . '"';
  711. else
  712. $placeholder = ' title="' . $langs->trans("RefOrLabel") . '"';
  713. if ($hidelabel == 2) {
  714. print img_picto($langs->trans("Search"), 'search');
  715. }
  716. }
  717. print '<input type="text" size="20" name="search_' . $htmlname . '" id="search_' . $htmlname . '" value="' . $selected_input_value . '"' . $placeholder . ' />';
  718. if ($hidelabel == 3) {
  719. print img_picto($langs->trans("Search"), 'search');
  720. }
  721. } else {
  722. $this->select_produits_do($selected, $htmlname, $filtertype, $limit, $price_level, '', $status, $finished, 0);
  723. }
  724. }
  725. /**
  726. * Return list of products for a customer
  727. *
  728. * @param int $selected Preselected product
  729. * @param string $htmlname Name of select html
  730. * @param string $filtertype Filter on product type (''=nofilter, 0=product, 1=service)
  731. * @param int $limit Limite sur le nombre de lignes retournees
  732. * @param int $price_level Level of price to show
  733. * @param string $filterkey Filter on product
  734. * @param int $status -1=Return all products, 0=Products not on sell, 1=Products on sell
  735. * @param int $finished Filter on finished field: 2=No filter
  736. * @param int $disableout Disable print output
  737. * @return array Array of keys for json
  738. */
  739. function select_produits_do($selected = '', $htmlname = 'productid', $filtertype = '', $limit = 20, $price_level = 0, $filterkey = '', $status = 1, $finished = 2, $disableout = 0) {
  740. return false;
  741. /*
  742. global $langs, $conf, $user, $db;
  743. $sql = "SELECT ";
  744. $sql.= " p.rowid, p.label, p.ref, p.description, p.fk_product_type, p.price, p.price_ttc, p.price_base_type, p.tva_tx, p.duration, p.stock";
  745. // Multilang : we add translation
  746. if (!empty($conf->global->MAIN_MULTILANGS)) {
  747. $sql.= ", pl.label as label_translated";
  748. }
  749. $sql.= " FROM " . MAIN_DB_PREFIX . "product as p";
  750. // Multilang : we add translation
  751. if (!empty($conf->global->MAIN_MULTILANGS)) {
  752. $sql.= " LEFT JOIN " . MAIN_DB_PREFIX . "product_lang as pl ON pl.fk_product = p.rowid AND pl.lang='" . $langs->getDefaultLang() . "'";
  753. }
  754. $sql.= ' WHERE p.entity IN (' . getEntity('product', 1) . ')';
  755. if ($finished == 0) {
  756. $sql.= " AND p.finished = " . $finished;
  757. } elseif ($finished == 1) {
  758. $sql.= " AND p.finished = " . $finished;
  759. if ($status >= 0)
  760. $sql.= " AND p.tosell = " . $status;
  761. }
  762. elseif ($status >= 0) {
  763. $sql.= " AND p.tosell = " . $status;
  764. }
  765. if (strval($filtertype) != '')
  766. $sql.=" AND p.fk_product_type=" . $filtertype;
  767. // Add criteria on ref/label
  768. if ($filterkey && $filterkey != '') {
  769. if (!empty($conf->global->PRODUCT_DONOTSEARCH_ANYWHERE)) { // Can use index
  770. $sql.=" AND (p.ref LIKE '" . $filterkey . "%' OR p.label LIKE '" . $filterkey . "%'";
  771. if (!empty($conf->global->MAIN_MULTILANGS))
  772. $sql.=" OR pl.label LIKE '" . $filterkey . "%'";
  773. $sql.=")";
  774. }
  775. else {
  776. $sql.=" AND (p.ref LIKE '%" . $filterkey . "%' OR p.label LIKE '%" . $filterkey . "%'";
  777. if (!empty($conf->global->MAIN_MULTILANGS))
  778. $sql.=" OR pl.label LIKE '%" . $filterkey . "%'";
  779. $sql.=")";
  780. }
  781. if (!empty($conf->barcode->enabled)) {
  782. $sql .= " OR p.barcode LIKE '" . $filterkey . "'";
  783. }
  784. }
  785. $sql.= $db->order("p.ref");
  786. $sql.= $db->plimit($limit);
  787. // Build output string
  788. $outselect = '';
  789. $outjson = array();
  790. $result = $this->db->query($sql);
  791. if ($result) {
  792. $num = $this->db->num_rows($result);
  793. $outselect.='<select class="flat" name="' . $htmlname . '" id="' . $htmlname . '">';
  794. $outselect.='<option value="0" selected="selected">&nbsp;</option>';
  795. $i = 0;
  796. while ($num && $i < $num) {
  797. $outkey = '';
  798. $outval = '';
  799. $outref = '';
  800. $outlabel = '';
  801. $outdesc = '';
  802. $outtype = '';
  803. $outprice_ht = '';
  804. $outprice_ttc = '';
  805. $outpricebasetype = '';
  806. $outtva_tx = '';
  807. $objp = $this->db->fetch_object($result);
  808. $label = $objp->label;
  809. if (!empty($objp->label_translated))
  810. $label = $objp->label_translated;
  811. if ($filterkey && $filterkey != '')
  812. $label = preg_replace('/(' . preg_quote($filterkey) . ')/i', '<strong>$1</strong>', $label, 1);
  813. $outkey = $objp->rowid;
  814. $outref = $objp->ref;
  815. $outlabel = $objp->label;
  816. $outdesc = $objp->description;
  817. $outtype = $objp->fk_product_type;
  818. $opt = '<option value="' . $objp->rowid . '"';
  819. $opt.= ($objp->rowid == $selected) ? ' selected="selected"' : '';
  820. if (!empty($conf->stock->enabled) && $objp->fk_product_type == 0 && isset($objp->stock)) {
  821. if ($objp->stock > 0) {
  822. $opt.= ' style="background-color:#32CD32; color:#F5F5F5;"';
  823. } else if ($objp->stock <= 0) {
  824. $opt.= ' style="background-color:#FF0000; color:#F5F5F5;"';
  825. }
  826. }
  827. $opt.= '>';
  828. $opt.= $objp->ref . ' - ' . dol_trunc($label, 32) . ' - ';
  829. $objRef = $objp->ref;
  830. if ($filterkey && $filterkey != '')
  831. $objRef = preg_replace('/(' . preg_quote($filterkey) . ')/i', '<strong>$1</strong>', $objRef, 1);
  832. $outval.=$objRef . ' - ' . dol_trunc($label, 32) . ' - ';
  833. $found = 0;
  834. $currencytext = $langs->trans("Currency" . $conf->currency);
  835. $currencytextnoent = $langs->transnoentities("Currency" . $conf->currency);
  836. if (dol_strlen($currencytext) > 10)
  837. $currencytext = $conf->currency; // If text is too long, we use the short code
  838. if (dol_strlen($currencytextnoent) > 10)
  839. $currencytextnoent = $conf->currency; // If text is too long, we use the short code
  840. // Multiprice
  841. if ($price_level >= 1) { // If we need a particular price level (from 1 to 6)
  842. $sql = "SELECT price, price_ttc, price_base_type, tva_tx";
  843. $sql.= " FROM " . MAIN_DB_PREFIX . "product_price";
  844. $sql.= " WHERE fk_product='" . $objp->rowid . "'";
  845. $sql.= " AND price_level=" . $price_level;
  846. $sql.= " ORDER BY date_price";
  847. $sql.= " DESC LIMIT 1";
  848. dol_syslog(get_class($this) . "::select_produits_do search price for level '.$price_level.' sql=" . $sql);
  849. $result2 = $this->db->query($sql);
  850. if ($result2) {
  851. $objp2 = $this->db->fetch_object($result2);
  852. if ($objp2) {
  853. $found = 1;
  854. if ($objp2->price_base_type == 'HT') {
  855. $opt.= price($objp2->price, 1) . ' ' . $currencytext . ' ' . $langs->trans("HT");
  856. $outval.= price($objp2->price, 1) . ' ' . $currencytextnoent . ' ' . $langs->transnoentities("HT");
  857. } else {
  858. $opt.= price($objp2->price_ttc, 1) . ' ' . $currencytext . ' ' . $langs->trans("TTC");
  859. $outval.= price($objp2->price_ttc, 1) . ' ' . $currencytextnoent . ' ' . $langs->transnoentities("TTC");
  860. }
  861. $outprice_ht = price($objp2->price);
  862. $outprice_ttc = price($objp2->price_ttc);
  863. $outpricebasetype = $objp2->price_base_type;
  864. $outtva_tx = $objp2->tva_tx;
  865. }
  866. } else {
  867. dol_print_error($this->db);
  868. }
  869. }
  870. // If level no defined or multiprice not found, we used the default price
  871. if (!$found) {
  872. if ($objp->price_base_type == 'HT') {
  873. $opt.= price($objp->price, 1) . ' ' . $currencytext . ' ' . $langs->trans("HT");
  874. $outval.= price($objp->price, 1) . ' ' . $currencytextnoent . ' ' . $langs->transnoentities("HT");
  875. } else {
  876. $opt.= price($objp->price_ttc, 1) . ' ' . $currencytext . ' ' . $langs->trans("TTC");
  877. $outval.= price($objp->price_ttc, 1) . ' ' . $currencytextnoent . ' ' . $langs->transnoentities("TTC");
  878. }
  879. $outprice_ht = price($objp->price);
  880. $outprice_ttc = price($objp->price_ttc);
  881. $outpricebasetype = $objp->price_base_type;
  882. $outtva_tx = $objp->tva_tx;
  883. }
  884. if (!empty($conf->stock->enabled) && isset($objp->stock) && $objp->fk_product_type == 0) {
  885. $opt.= ' - ' . $langs->trans("Stock") . ':' . $objp->stock;
  886. $outval.=' - ' . $langs->transnoentities("Stock") . ':' . $objp->stock;
  887. }
  888. if ($objp->duration) {
  889. $duration_value = substr($objp->duration, 0, dol_strlen($objp->duration) - 1);
  890. $duration_unit = substr($objp->duration, -1);
  891. if ($duration_value > 1) {
  892. $dur = array("h" => $langs->trans("Hours"), "d" => $langs->trans("Days"), "w" => $langs->trans("Weeks"), "m" => $langs->trans("Months"), "y" => $langs->trans("Years"));
  893. } else {
  894. $dur = array("h" => $langs->trans("Hour"), "d" => $langs->trans("Day"), "w" => $langs->trans("Week"), "m" => $langs->trans("Month"), "y" => $langs->trans("Year"));
  895. }
  896. $opt.= ' - ' . $duration_value . ' ' . $langs->trans($dur[$duration_unit]);
  897. $outval.=' - ' . $duration_value . ' ' . $langs->transnoentities($dur[$duration_unit]);
  898. }
  899. $opt.= "</option>\n";
  900. // Add new entry
  901. // "key" value of json key array is used by jQuery automatically as selected value
  902. // "label" value of json key array is used by jQuery automatically as text for combo box
  903. $outselect.=$opt;
  904. array_push($outjson, array('key' => $outkey, 'value' => $outref, 'label' => $outval, 'label2' => $outlabel, 'desc' => $outdesc, 'type' => $outtype, 'price_ht' => $outprice_ht, 'price_ttc' => $outprice_ttc, 'pricebasetype' => $outpricebasetype, 'tva_tx' => $outtva_tx));
  905. $i++;
  906. }
  907. $outselect.='</select>';
  908. $this->db->free($result);
  909. if (empty($disableout))
  910. print $outselect;
  911. return $outjson;
  912. }
  913. else {
  914. dol_print_error($db);
  915. }
  916. */
  917. }
  918. /**
  919. * Return list of products for a customer
  920. *
  921. * @param int $selected Preselected product
  922. * @param string $htmlname Name of select html
  923. * @param string $filtertype Filter on product type (''=nofilter, 0=product, 1=service)
  924. * @param int $limit Limite sur le nombre de lignes retournees
  925. * @param int $price_level Level of price to show
  926. * @param string $filterkey Filter on product
  927. * @param int $status -1=Return all products, 0=Products not on sell, 1=Products on sell
  928. * @param int $finished Filter on finished field: 2=No filter
  929. * @param int $disableout Disable print output
  930. * @return array Array of keys for json
  931. */
  932. function select_products($selected = '', $htmlname = 'productid', $filtertype = '', $limit = 20, $price_level = 0, $filterkey = '', $status = 1, $finished = 2, $disableout = 0) {
  933. global $langs, $conf, $user, $db;
  934. require_once(DOL_DOCUMENT_ROOT . '/product/class/product.class.php');
  935. $object = new Product($db);
  936. $result = $object->getView('list', array('startkey' => $filterkey, 'endkey' => $filterkey . 'Z'));
  937. // $sql = "SELECT ";
  938. // $sql.= " p.rowid, p.label, p.ref, p.description, p.fk_product_type, p.price, p.price_ttc, p.price_base_type, p.tva_tx, p.duration, p.stock";
  939. // // Multilang : we add translation
  940. // if (!empty($conf->global->MAIN_MULTILANGS)) {
  941. // $sql.= ", pl.label as label_translated";
  942. // }
  943. // $sql.= " FROM " . MAIN_DB_PREFIX . "product as p";
  944. // // Multilang : we add translation
  945. // if (!empty($conf->global->MAIN_MULTILANGS)) {
  946. // $sql.= " LEFT JOIN " . MAIN_DB_PREFIX . "product_lang as pl ON pl.fk_product = p.rowid AND pl.lang='" . $langs->getDefaultLang() . "'";
  947. // }
  948. // $sql.= ' WHERE p.entity IN (' . getEntity('product', 1) . ')';
  949. // if ($finished == 0) {
  950. // $sql.= " AND p.finished = " . $finished;
  951. // } elseif ($finished == 1) {
  952. // $sql.= " AND p.finished = " . $finished;
  953. // if ($status >= 0)
  954. // $sql.= " AND p.tosell = " . $status;
  955. // }
  956. // elseif ($status >= 0) {
  957. // $sql.= " AND p.tosell = " . $status;
  958. // }
  959. // if (strval($filtertype) != '')
  960. // $sql.=" AND p.fk_product_type=" . $filtertype;
  961. // // Add criteria on ref/label
  962. // if ($filterkey && $filterkey != '') {
  963. // if (!empty($conf->global->PRODUCT_DONOTSEARCH_ANYWHERE)) { // Can use index
  964. // $sql.=" AND (p.ref LIKE '" . $filterkey . "%' OR p.label LIKE '" . $filterkey . "%'";
  965. // if (!empty($conf->global->MAIN_MULTILANGS))
  966. // $sql.=" OR pl.label LIKE '" . $filterkey . "%'";
  967. // $sql.=")";
  968. // }
  969. // else {
  970. // $sql.=" AND (p.ref LIKE '%" . $filterkey . "%' OR p.label LIKE '%" . $filterkey . "%'";
  971. // if (!empty($conf->global->MAIN_MULTILANGS))
  972. // $sql.=" OR pl.label LIKE '%" . $filterkey . "%'";
  973. // $sql.=")";
  974. // }
  975. //
  976. // if (!empty($conf->barcode->enabled)) {
  977. // $sql .= " OR p.barcode LIKE '" . $filterkey . "'";
  978. // }
  979. // }
  980. // $sql.= $db->order("p.ref");
  981. // $sql.= $db->plimit($limit);
  982. //
  983. // // Build output string
  984. $outselect = '';
  985. $outjson = array();
  986. //
  987. // dol_syslog(get_class($this) . "::select_produits_do search product sql=" . $sql, LOG_DEBUG);
  988. // $result = $this->db->query($sql);
  989. if (!empty($result->rows)) {
  990. $num = count($result->rows);
  991. $outselect.='<select class="flat" name="' . $htmlname . '" id="' . $htmlname . '">';
  992. $outselect.='<option value="0" selected="selected">&nbsp;</option>';
  993. $i = 0;
  994. while ($num && $i < $num) {
  995. $outkey = '';
  996. $outval = '';
  997. $outref = '';
  998. $outlabel = '';
  999. $outdesc = '';
  1000. $outtype = '';
  1001. $outprice_ht = '';
  1002. $outprice_ttc = '';
  1003. $outpricebasetype = '';
  1004. $outtva_tx = '';
  1005. // $objp = $this->db->fetch_object($result);
  1006. $objp = new Product($db);
  1007. $objp->fetch($result->rows[$i]->value->_id);
  1008. $label = $objp->label;
  1009. if (!empty($objp->label_translated))
  1010. $label = $objp->label_translated;
  1011. if ($filterkey && $filterkey != '')
  1012. $label = preg_replace('/(' . preg_quote($filterkey) . ')/i', '<strong>$1</strong>', $label, 1);
  1013. $outkey = $objp->id;
  1014. $outref = $objp->name;
  1015. $outlabel = $objp->label;
  1016. $outdesc = isset($objp->description) ? $objp->description : '';
  1017. $outtype = $objp->type;
  1018. $opt = '<option value="' . $objp->id . '"';
  1019. $opt.= ($objp->id == $selected) ? ' selected="selected"' : '';
  1020. if (!empty($conf->stock->enabled) && $objp->type == 'PRODUCT' && isset($objp->stock)) {
  1021. if ($objp->stock > 0) {
  1022. $opt.= ' style="background-color:#32CD32; color:#F5F5F5;"';
  1023. } else if ($objp->stock <= 0) {
  1024. $opt.= ' style="background-color:#FF0000; color:#F5F5F5;"';
  1025. }
  1026. }
  1027. $opt.= '>';
  1028. $opt.= $objp->name . ' - ' . dol_trunc($label, 32) . ' - ';
  1029. $objRef = $objp->name;
  1030. if ($filterkey && $filterkey != '')
  1031. $objRef = preg_replace('/(' . preg_quote($filterkey) . ')/i', '<strong>$1</strong>', $objRef, 1);
  1032. $outval.=$objRef . ' - ' . dol_trunc($label, 32) . ' - ';
  1033. $found = 0;
  1034. $currencytext = $langs->trans("Currency" . $conf->currency);
  1035. $currencytextnoent = $langs->transnoentities("Currency" . $conf->currency);
  1036. if (dol_strlen($currencytext) > 10)
  1037. $currencytext = $conf->currency; // If text is too long, we use the short code
  1038. if (dol_strlen($currencytextnoent) > 10)
  1039. $currencytextnoent = $conf->currency; // If text is too long, we use the short code
  1040. // Multiprice
  1041. // if ($price_level >= 1) { // If we need a particular price level (from 1 to 6)
  1042. // $sql = "SELECT price, price_ttc, price_base_type, tva_tx";
  1043. // $sql.= " FROM " . MAIN_DB_PREFIX . "product_price";
  1044. // $sql.= " WHERE fk_product='" . $objp->rowid . "'";
  1045. // $sql.= " AND price_level=" . $price_level;
  1046. // $sql.= " ORDER BY date_price";
  1047. // $sql.= " DESC LIMIT 1";
  1048. //
  1049. // dol_syslog(get_class($this) . "::select_produits_do search price for level '.$price_level.' sql=" . $sql);
  1050. // $result2 = $this->db->query($sql);
  1051. // if ($result2) {
  1052. // $objp2 = $this->db->fetch_object($result2);
  1053. // if ($objp2) {
  1054. // $found = 1;
  1055. // if ($objp2->price_base_type == 'HT') {
  1056. // $opt.= price($objp2->price, 1) . ' ' . $currencytext . ' ' . $langs->trans("HT");
  1057. // $outval.= price($objp2->price, 1) . ' ' . $currencytextnoent . ' ' . $langs->transnoentities("HT");
  1058. // } else {
  1059. // $opt.= price($objp2->price_ttc, 1) . ' ' . $currencytext . ' ' . $langs->trans("TTC");
  1060. // $outval.= price($objp2->price_ttc, 1) . ' ' . $currencytextnoent . ' ' . $langs->transnoentities("TTC");
  1061. // }
  1062. // $outprice_ht = price($objp2->price);
  1063. // $outprice_ttc = price($objp2->price_ttc);
  1064. // $outpricebasetype = $objp2->price_base_type;
  1065. // $outtva_tx = $objp2->tva_tx;
  1066. // }
  1067. // } else {
  1068. // dol_print_error($this->db);
  1069. // }
  1070. // }
  1071. // If level no defined or multiprice not found, we used the default price
  1072. if (!$found) {
  1073. if ($objp->price->price_base_type == 'HT') {
  1074. $opt.= price($objp->price->price, 1) . ' ' . $currencytext . ' ' . $langs->trans("HT");
  1075. $outval.= price($objp->price->price, 1) . ' ' . $currencytextnoent . ' ' . $langs->transnoentities("HT");
  1076. } else {
  1077. $opt.= price($objp->price->price_ttc, 1) . ' ' . $currencytext . ' ' . $langs->trans("TTC");
  1078. $outval.= price($objp->price->price_ttc, 1) . ' ' . $currencytextnoent . ' ' . $langs->transnoentities("TTC");
  1079. }
  1080. $outprice_ht = price($objp->price->price);
  1081. $outprice_ttc = price($objp->price->price_ttc);
  1082. $outpricebasetype = $objp->price->price_base_type;
  1083. $outtva_tx = $objp->price->tva_tx;
  1084. }
  1085. if (!empty($conf->stock->enabled) && isset($objp->stock) && $objp->type == "PRODUCT") {
  1086. $opt.= ' - ' . $langs->trans("Stock") . ':' . $objp->stock;
  1087. $outval.=' - ' . $langs->transnoentities("Stock") . ':' . $objp->stock;
  1088. }
  1089. if ($objp->duration) {
  1090. $duration_value = substr($objp->duration, 0, dol_strlen($objp->duration) - 1);
  1091. $duration_unit = substr($objp->duration, -1);
  1092. if ($duration_value > 1) {
  1093. $dur = array("h" => $langs->trans("Hours"), "d" => $langs->trans("Days"), "w" => $langs->trans("Weeks"), "m" => $langs->trans("Months"), "y" => $langs->trans("Years"));
  1094. } else {
  1095. $dur = array("h" => $langs->trans("Hour"), "d" => $langs->trans("Day"), "w" => $langs->trans("Week"), "m" => $langs->trans("Month"), "y" => $langs->trans("Year"));
  1096. }
  1097. $opt.= ' - ' . $duration_value . ' ' . $langs->trans($dur[$duration_unit]);
  1098. $outval.=' - ' . $duration_value . ' ' . $langs->transnoentities($dur[$duration_unit]);
  1099. }
  1100. $opt.= "</option>\n";
  1101. // Add new entry
  1102. // "key" value of json key array is used by jQuery automatically as selected value
  1103. // "label" value of json key array is used by jQuery automatically as text for combo box
  1104. $outselect.=$opt;
  1105. array_push($outjson, array('key' => $outkey, 'value' => $outref, 'label' => $outval, 'label2' => $outlabel, 'desc' => $outdesc, 'type' => $outtype, 'price_ht' => $outprice_ht, 'price_ttc' => $outprice_ttc, 'pricebasetype' => $outpricebasetype, 'tva_tx' => $outtva_tx));
  1106. $i++;
  1107. }
  1108. $outselect.='</select>';
  1109. // $this->db->free($result);
  1110. if (empty($disableout))
  1111. print $outselect;
  1112. return $outjson;
  1113. }
  1114. }
  1115. /**
  1116. * Return list of products for customer (in Ajax if Ajax activated or go to select_produits_fournisseurs_do)
  1117. *
  1118. * @param int $socid Id third party
  1119. * @param string $selected Preselected product
  1120. * @param string $htmlname Name of HTML Select
  1121. * @param string $filtertype Filter on product type (''=nofilter, 0=product, 1=service)
  1122. * @param string $filtre For a SQL filter
  1123. * @param array $ajaxopt…

Large files files are truncated, but you can click here to view the full file