From d6514e1cd66af2cb9d58444f768eb65990f23c2e Mon Sep 17 00:00:00 2001
From: fhenry <florian.henry@open-concept.pro>
Date: Sun, 21 Apr 2013 17:36:23 +0200
Subject: [PATCH] Add extrafield select from table

---
 htdocs/core/class/extrafields.class.php       | 886 ++++++++++--------
 htdocs/core/tpl/admin_extrafields_add.tpl.php |   6 +-
 .../core/tpl/admin_extrafields_edit.tpl.php   |   7 +-
 htdocs/langs/ca_ES/admin.lang                 |   5 +-
 htdocs/langs/en_US/admin.lang                 |   5 +-
 htdocs/langs/es_ES/admin.lang                 |   5 +-
 htdocs/langs/fr_FR/admin.lang                 |   5 +-
 7 files changed, 502 insertions(+), 417 deletions(-)

diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php
index aae14dba217..e2986615dde 100755
--- a/htdocs/core/class/extrafields.class.php
+++ b/htdocs/core/class/extrafields.class.php
@@ -1,34 +1,34 @@
 <?php
 /* Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  * Copyright (C) 2002-2003 Jean-Louis Bergamo   <jlb@j1b.org>
- * Copyright (C) 2004      Sebastien Di Cintio  <sdicintio@ressource-toi.org>
- * Copyright (C) 2004      Benoit Mortier	    <benoit.mortier@opensides.be>
- * Copyright (C) 2009-2012 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) 2009-2012 Regis Houssin        <regis.houssin@capnetworks.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
+* Copyright (C) 2004      Sebastien Di Cintio  <sdicintio@ressource-toi.org>
+* Copyright (C) 2004      Benoit Mortier	    <benoit.mortier@opensides.be>
+* Copyright (C) 2009-2012 Laurent Destailleur  <eldy@users.sourceforge.net>
+* Copyright (C) 2009-2012 Regis Houssin        <regis.houssin@capnetworks.com>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
 
 /**
  * 	\file 		htdocs/core/class/extrafields.class.php
- *	\ingroup    core
- *	\brief      File of class to manage extra fields
- */
+*	\ingroup    core
+*	\brief      File of class to manage extra fields
+*/
 
 /**
  *	Class to manage standard extra fields
- */
+*/
 class ExtraFields
 {
 	var $db;
@@ -53,27 +53,29 @@ class ExtraFields
 	var $errno;
 
 	static $type2label=array(
-		'varchar'=>'String',
-		'text'=>'TextLong',
-		'int'=>'Int',
-		'double'=>'Float',
-		'date'=>'Date',
-		'datetime'=>'DateAndTime',
-		'boolean'=>'Boolean',
-		'price'=>'ExtrafieldPrice',
-		'phone'=>'ExtrafieldPhone',
-		'mail'=>'ExtrafieldMail',
-		'select' => 'ExtrafieldSelect',
-		'separate' => 'ExtrafieldSeparator',
-		'checkbox' => 'ExtrafieldCheckBox',
-		'radio' => 'ExtrafieldRadio',
+	'varchar'=>'String',
+	'text'=>'TextLong',
+	'int'=>'Int',
+	'double'=>'Float',
+	'date'=>'Date',
+	'datetime'=>'DateAndTime',
+	'boolean'=>'Boolean',
+	'price'=>'ExtrafieldPrice',
+	'phone'=>'ExtrafieldPhone',
+	'mail'=>'ExtrafieldMail',
+	'select' => 'ExtrafieldSelect',
+	'sellist' => 'ExtrafieldSelectList',
+	'separate' => 'ExtrafieldSeparator',
+	'checkbox' => 'ExtrafieldCheckBox',
+	'radio' => 'ExtrafieldRadio',
+
 	);
 
 	/**
 	 *	Constructor
 	 *
 	 *  @param		DoliDB		$db      Database handler
-	 */
+	*/
 	function __construct($db)
 	{
 		$this->db = $db;
@@ -86,49 +88,49 @@ class ExtraFields
 		$this->attribute_required = array();
 	}
 
-    /**
-     *  Add a new extra field parameter
-     *
-     *  @param	string	$attrname           Code of attribute
-     *  @param  string	$label              label of attribute
-     *  @param  int		$type               Type of attribute ('int', 'text', 'varchar', 'date', 'datehour')
-     *  @param  int		$pos                Position of attribute
-     *  @param  int		$size               Size/length of attribute
-     *  @param  string	$elementtype        Element type ('member', 'product', 'company', ...)
-     *  @param	int		$unique				Is field unique or not
-     *  @param	int		$required			Is field required or not
-     *  @param	string	$default_value		Defaulted value
-     *  @param  array	$param				Params for field 
-     *  @return int      					<=0 if KO, >0 if OK
-     */
-    function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0,$default_value='', $param=0)
+	/**
+	 *  Add a new extra field parameter
+	 *
+	 *  @param	string	$attrname           Code of attribute
+	 *  @param  string	$label              label of attribute
+	 *  @param  int		$type               Type of attribute ('int', 'text', 'varchar', 'date', 'datehour')
+	 *  @param  int		$pos                Position of attribute
+	 *  @param  int		$size               Size/length of attribute
+	 *  @param  string	$elementtype        Element type ('member', 'product', 'company', ...)
+	 *  @param	int		$unique				Is field unique or not
+	 *  @param	int		$required			Is field required or not
+	 *  @param	string	$default_value		Defaulted value
+	 *  @param  array	$param				Params for field
+	 *  @return int      					<=0 if KO, >0 if OK
+	 */
+	function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0,$default_value='', $param=0)
 	{
-        if (empty($attrname)) return -1;
-        if (empty($label)) return -1;
-
-        // Create field into database except for separator type which is not stored in database
-        if ($type != 'separate')
-        {
-        	$result=$this->create($attrname,$type,$size,$elementtype, $unique, $required, $default_value,$param);
-        }
-        $err1=$this->errno;
-        if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate')
-        {
-        	// Add declaration of field into table
-            $result2=$this->create_label($attrname,$label,$type,$pos,$size,$elementtype, $unique, $required, $param);
-            $err2=$this->errno;
-            if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS'))
-            {
-                $this->error='';
-                $this->errno=0;
-                return 1;
-            }
-            else return -2;
-        }
-        else
-        {
-            return -1;
-        }
+		if (empty($attrname)) return -1;
+		if (empty($label)) return -1;
+
+		// Create field into database except for separator type which is not stored in database
+		if ($type != 'separate')
+		{
+			$result=$this->create($attrname,$type,$size,$elementtype, $unique, $required, $default_value,$param);
+		}
+		$err1=$this->errno;
+		if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate')
+		{
+			// Add declaration of field into table
+			$result2=$this->create_label($attrname,$label,$type,$pos,$size,$elementtype, $unique, $required, $param);
+			$err2=$this->errno;
+			if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS'))
+			{
+				$this->error='';
+				$this->errno=0;
+				return 1;
+			}
+			else return -2;
+		}
+		else
+		{
+			return -1;
+		}
 	}
 
 	/**
@@ -138,22 +140,22 @@ class ExtraFields
 	 *	@param	string	$attrname			code of attribute
 	 *  @param	int		$type				Type of attribute ('int', 'text', 'varchar', 'date', 'datehour')
 	 *  @param	int		$length				Size/length of attribute
-     *  @param  string	$elementtype        Element type ('member', 'product', 'company', 'contact', ...)
-     *  @param	int		$unique				Is field unique or not
-     *  @param	int		$required			Is field required or not
-     *  @param  string  $default_value		Default value for field
-     *  @param  array	$param				Params for field  (ex for select list : array('options'=>array('value'=>'label of option'))
-     *  
-     *  @return int      	           		<=0 if KO, >0 if OK
+	 *  @param  string	$elementtype        Element type ('member', 'product', 'company', 'contact', ...)
+	 *  @param	int		$unique				Is field unique or not
+	 *  @param	int		$required			Is field required or not
+	 *  @param  string  $default_value		Default value for field
+	 *  @param  array	$param				Params for field  (ex for select list : array('options'=>array('value'=>'label of option'))
+	 *
+	 *  @return int      	           		<=0 if KO, >0 if OK
 	 */
 	private function create($attrname, $type='varchar', $length=255, $elementtype='member', $unique=0, $required=0, $default_value='',$param='')
 	{
-        $table=$elementtype.'_extrafields';
-        
-        // Special case for not normalized table names
-        if ($elementtype == 'member')  $table='adherent_extrafields';
-        elseif ($elementtype == 'company') $table='societe_extrafields';
-        elseif ($elementtype == 'contact') $table='socpeople_extrafields';
+		$table=$elementtype.'_extrafields';
+
+		// Special case for not normalized table names
+		if ($elementtype == 'member')  $table='adherent_extrafields';
+		elseif ($elementtype == 'company') $table='societe_extrafields';
+		elseif ($elementtype == 'contact') $table='socpeople_extrafields';
 
 		if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname))
 		{
@@ -169,7 +171,7 @@ class ExtraFields
 			}elseif($type=='mail') {
 				$typedb='varchar';
 				$lengthdb='128';
-			} elseif (($type=='select') || ($type=='radio') ||($type=='checkbox')){
+			} elseif (($type=='select') || ($type=='sellist') || ($type=='radio') ||($type=='checkbox')){
 				$typedb='text';
 				$lengthdb='';
 			} else {
@@ -177,12 +179,12 @@ class ExtraFields
 				$lengthdb=$length;
 			}
 			$field_desc = array(
-				'type'=>$typedb, 
-				'value'=>$lengthdb, 
-				'null'=>($required?'NOT NULL':'NULL'),
-				'default' => $default_value
+			'type'=>$typedb,
+			'value'=>$lengthdb,
+			'null'=>($required?'NOT NULL':'NULL'),
+			'default' => $default_value
 			);
-			
+
 			$result=$this->db->DDLAddField(MAIN_DB_PREFIX.$table, $attrname, $field_desc);
 			if ($result > 0)
 			{
@@ -215,9 +217,9 @@ class ExtraFields
 	 *  @param	int		$pos				Position of attribute
 	 *  @param	int		$size				Size/length of attribute
 	 *  @param  string	$elementtype        Element type ('member', 'product', 'company', ...)
-     *  @param	int		$unique				Is field unique or not
-     *  @param	int		$required			Is field required or not
-     *  @param  array	$param				Params for field  (ex for select list : array('options' => array(value'=>'label of option')) )
+	 *  @param	int		$unique				Is field unique or not
+	 *  @param	int		$required			Is field required or not
+	 *  @param  array	$param				Params for field  (ex for select list : array('options' => array(value'=>'label of option')) )
 	 *  @return	int							<=0 if KO, >0 if OK
 	 */
 	private function create_label($attrname, $label='', $type='', $pos=0, $size=0, $elementtype='member', $unique=0, $required=0, $param='')
@@ -227,7 +229,7 @@ class ExtraFields
 		// Clean parameters
 		if (empty($pos)) $pos=0;
 
-		
+
 		if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname))
 		{
 			if(is_array($param) and count($param) > 0)
@@ -242,7 +244,7 @@ class ExtraFields
 			{
 				$params='';
 			}
-			
+
 			$sql = "INSERT INTO ".MAIN_DB_PREFIX."extrafields(name, label, type, pos, size, entity, elementtype, fieldunique, fieldrequired, param)";
 			$sql.= " VALUES('".$attrname."',";
 			$sql.= " '".$this->db->escape($label)."',";
@@ -250,11 +252,11 @@ class ExtraFields
 			$sql.= " '".$pos."',";
 			$sql.= " '".$size."',";
 			$sql.= " ".$conf->entity.",";
-            $sql.= " '".$elementtype."',";
-            $sql.= " '".$unique."',";
-            $sql.= " '".$required."',";
-            $sql.= " '".$params."'";
-            $sql.=')';
+			$sql.= " '".$elementtype."',";
+			$sql.= " '".$unique."',";
+			$sql.= " '".$required."',";
+			$sql.= " '".$params."'";
+			$sql.=')';
 
 			dol_syslog(get_class($this)."::create_label sql=".$sql);
 			if ($this->db->query($sql))
@@ -279,16 +281,16 @@ class ExtraFields
 	 */
 	function delete($attrname, $elementtype='member')
 	{
-        $table=$elementtype.'_extrafields';
+		$table=$elementtype.'_extrafields';
 
-        // Special case for not normalized table names
-        if ($elementtype == 'member')  $table='adherent_extrafields';
-        elseif ($elementtype == 'company') $table='societe_extrafields';
-        elseif ($elementtype == 'contact') $table='socpeople_extrafields';
+		// Special case for not normalized table names
+		if ($elementtype == 'member')  $table='adherent_extrafields';
+		elseif ($elementtype == 'company') $table='societe_extrafields';
+		elseif ($elementtype == 'contact') $table='socpeople_extrafields';
 
 		if (! empty($attrname) && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname))
 		{
-		    $result=$this->db->DDLDropField(MAIN_DB_PREFIX.$table,$attrname);	// This also drop the unique key
+			$result=$this->db->DDLDropField(MAIN_DB_PREFIX.$table,$attrname);	// This also drop the unique key
 			if ($result < 0)
 			{
 				$this->error=$this->db->lasterror();
@@ -310,8 +312,8 @@ class ExtraFields
 	 *	Delete description of an optionnal attribute
 	 *
 	 *	@param	string	$attrname			Code of attribute to delete
-     *  @param  string	$elementtype        Element type ('member', 'product', 'company', ...)
-     *  @return int              			< 0 if KO, 0 if nothing is done, 1 if OK
+	 *  @param  string	$elementtype        Element type ('member', 'product', 'company', ...)
+	 *  @return int              			< 0 if KO, 0 if nothing is done, 1 if OK
 	 */
 	private function delete_label($attrname, $elementtype='member')
 	{
@@ -322,7 +324,7 @@ class ExtraFields
 			$sql = "DELETE FROM ".MAIN_DB_PREFIX."extrafields";
 			$sql.= " WHERE name = '".$attrname."'";
 			$sql.= " AND entity = ".$conf->entity;
-            $sql.= " AND elementtype = '".$elementtype."'";
+			$sql.= " AND elementtype = '".$elementtype."'";
 
 			dol_syslog(get_class($this)."::delete_label sql=".$sql);
 			$resql=$this->db->query($sql);
@@ -350,22 +352,22 @@ class ExtraFields
 	 *  @param	string	$label				Label of attribute
 	 *  @param	string	$type				Type of attribute
 	 *  @param	int		$length				Length of attribute
-     *  @param  string	$elementtype        Element type ('member', 'product', 'company', 'contact', ...)
-     *  @param	int		$unique				Is field unique or not
-     *  @param	int		$required			Is field required or not
-     *  @param	int		$pos				Position of attribute
-     *  @param  array	$param				Params for field  (ex for select list : array('options' => array(value'=>'label of option')) )
+	 *  @param  string	$elementtype        Element type ('member', 'product', 'company', 'contact', ...)
+	 *  @param	int		$unique				Is field unique or not
+	 *  @param	int		$required			Is field required or not
+	 *  @param	int		$pos				Position of attribute
+	 *  @param  array	$param				Params for field  (ex for select list : array('options' => array(value'=>'label of option')) )
 	 * 	@return	int							>0 if OK, <=0 if KO
 	 */
 	function update($attrname,$label,$type,$length,$elementtype,$unique=0,$required=0,$pos=0,$param='')
 	{
-        $table=$elementtype.'_extrafields';
-        // Special case for not normalized table names
-        if ($elementtype == 'member')  $table='adherent_extrafields';
-        elseif ($elementtype == 'company') $table='societe_extrafields';
-        elseif ($elementtype == 'contact') $table='socpeople_extrafields';
+		$table=$elementtype.'_extrafields';
+		// Special case for not normalized table names
+		if ($elementtype == 'member')  $table='adherent_extrafields';
+		elseif ($elementtype == 'company') $table='societe_extrafields';
+		elseif ($elementtype == 'contact') $table='socpeople_extrafields';
 
-        if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname))
+		if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname))
 		{
 			if ($type=='boolean') {
 				$typedb='int';
@@ -379,7 +381,7 @@ class ExtraFields
 			}elseif($type=='mail') {
 				$typedb='varchar';
 				$lengthdb='128';
-			} elseif (($type=='select') || ($type=='radio') ||($type=='checkbox')) {
+			} elseif (($type=='select') || ($type=='sellist') || ($type=='radio') ||($type=='checkbox')) {
 				$typedb='text';
 				$lengthdb='';
 			} else {
@@ -387,7 +389,7 @@ class ExtraFields
 				$lengthdb=$length;
 			}
 			$field_desc = array('type'=>$typedb, 'value'=>$lengthdb, 'null'=>($required?'NOT NULL':'NULL'));
-			
+
 			if ($type != 'separate') // No table update when separate type
 			{
 				$result=$this->db->DDLUpdateField(MAIN_DB_PREFIX.$table, $attrname, $field_desc);
@@ -437,15 +439,15 @@ class ExtraFields
 	 *
 	 *  @param	string	$attrname			Name of attribute
 	 *  @param	string	$label				Label of attribute
-     *  @param  string	$type               Type of attribute
-     *  @param  int		$size		        Length of attribute
-     *  @param  string	$elementtype		Element type ('member', 'product', 'company', ...)
-     *  @param	int		$unique				Is field unique or not
-     *  @param	int		$required			Is field required or not
-     *  @param	int		$pos				Position of attribute
-     *  @param  array	$param				Params for field  (ex for select list : array('options' => array(value'=>'label of option')) )
-     *  @return	int							<=0 if KO, >0 if OK
-     */
+	 *  @param  string	$type               Type of attribute
+	 *  @param  int		$size		        Length of attribute
+	 *  @param  string	$elementtype		Element type ('member', 'product', 'company', ...)
+	 *  @param	int		$unique				Is field unique or not
+	 *  @param	int		$required			Is field required or not
+	 *  @param	int		$pos				Position of attribute
+	 *  @param  array	$param				Params for field  (ex for select list : array('options' => array(value'=>'label of option')) )
+	 *  @return	int							<=0 if KO, >0 if OK
+	 */
 	private function update_label($attrname,$label,$type,$size,$elementtype,$unique=0,$required=0,$pos=0,$param='')
 	{
 		global $conf;
@@ -454,12 +456,12 @@ class ExtraFields
 		if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname))
 		{
 			$this->db->begin();
-			
+
 			if(is_array($param) && count($param) > 0)
 			{
 				$param = serialize($param);
 			}
-				
+
 			$sql_del = "DELETE FROM ".MAIN_DB_PREFIX."extrafields";
 			$sql_del.= " WHERE name = '".$attrname."'";
 			$sql_del.= " AND entity = ".$conf->entity;
@@ -484,12 +486,12 @@ class ExtraFields
 			$sql.= " '".$this->db->escape($label)."',";
 			$sql.= " '".$type."',";
 			$sql.= " '".$size."',";
-            $sql.= " '".$elementtype."',";
-            $sql.= " '".$unique."',";
-            $sql.= " '".$required."',";
-            $sql.= " '".$pos."',";
-            $sql.= " '".$param."'";
-            $sql.= ")";
+			$sql.= " '".$elementtype."',";
+			$sql.= " '".$unique."',";
+			$sql.= " '".$required."',";
+			$sql.= " '".$pos."',";
+			$sql.= " '".$param."'";
+			$sql.= ")";
 			dol_syslog(get_class($this)."::update_label sql=".$sql);
 			$resql2=$this->db->query($sql);
 
@@ -555,7 +557,7 @@ class ExtraFields
 			{
 				while ($tab = $this->db->fetch_object($resql))
 				{
-					
+
 					// we can add this attribute to adherent object
 					if ($tab->type != 'separate')
 					{
@@ -565,11 +567,11 @@ class ExtraFields
 					$this->attribute_type[$tab->name]=$tab->type;
 					$this->attribute_label[$tab->name]=$tab->label;
 					$this->attribute_size[$tab->name]=$tab->size;
-                    $this->attribute_elementtype[$tab->name]=$tab->elementtype;
-                    $this->attribute_unique[$tab->name]=$tab->fieldunique;
-                    $this->attribute_required[$tab->name]=$tab->fieldrequired;
-                    $this->attribute_param[$tab->name]=unserialize($tab->param);
-                    $this->attribute_pos[$tab->name]=$tab->pos;
+					$this->attribute_elementtype[$tab->name]=$tab->elementtype;
+					$this->attribute_unique[$tab->name]=$tab->fieldunique;
+					$this->attribute_required[$tab->name]=$tab->fieldrequired;
+					$this->attribute_param[$tab->name]=unserialize($tab->param);
+					$this->attribute_pos[$tab->name]=$tab->pos;
 				}
 			}
 			return $array_name_label;
@@ -593,268 +595,332 @@ class ExtraFields
 	{
 		global $conf,$langs;
 
-        $label=$this->attribute_label[$key];
-	    $type =$this->attribute_type[$key];
-        $size =$this->attribute_size[$key];
-        $elementtype=$this->attribute_elementtype[$key];
-        $unique=$this->attribute_unique[$key];
-        $required=$this->attribute_required[$key];
-        $param=$this->attribute_param[$key];
-        if ($type == 'date')
-        {
-            $showsize=10;
-        }
-        elseif ($type == 'datetime')
-        {
-            $showsize=19;
-        }
-        elseif (in_array($type,array('int','double')))
-        {
-            $showsize=10;
-        }
-        else
-        {
-            $showsize=round($size);
-            if ($showsize > 48) $showsize=48;
-        }
+		$label=$this->attribute_label[$key];
+		$type =$this->attribute_type[$key];
+		$size =$this->attribute_size[$key];
+		$elementtype=$this->attribute_elementtype[$key];
+		$unique=$this->attribute_unique[$key];
+		$required=$this->attribute_required[$key];
+		$param=$this->attribute_param[$key];
+		if ($type == 'date')
+		{
+			$showsize=10;
+		}
+		elseif ($type == 'datetime')
+		{
+			$showsize=19;
+		}
+		elseif (in_array($type,array('int','double')))
+		{
+			$showsize=10;
+		}
+		else
+		{
+			$showsize=round($size);
+			if ($showsize > 48) $showsize=48;
+		}
 
 		if (in_array($type,array('date','datetime')))
-        {
-        	$tmp=explode(',',$size);
-        	$newsize=$tmp[0];
-        	if(!class_exists('Form'))
-        		require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
-        	$formstat = new Form($db);
-        	
-        	$showtime = in_array($type,array('datetime')) ? 1 : 0;
-        	// Do not show current date when field not required (see select_date() method)
-        	if(!$required && $value == '')
-        		$value = '-1';
-        	
-        	$out = $formstat->select_date($value, 'options_'.$key, $showtime, $showtime, $required, '', 1, 1, 1, 0, 1);
-        	//$out='<input type="text" name="options_'.$key.'" size="'.$showsize.'" maxlength="'.$newsize.'" value="'.$value.'"'.($moreparam?$moreparam:'').'>';
-        }
-        elseif (in_array($type,array('int','double')))
-        {
-        	$tmp=explode(',',$size);
-        	$newsize=$tmp[0];
-        	$out='<input type="text" name="options_'.$key.'" size="'.$showsize.'" maxlength="'.$newsize.'" value="'.$value.'"'.($moreparam?$moreparam:'').'>';
-        }
-        elseif ($type == 'varchar')
-        {
-        	$out='<input type="text" name="options_'.$key.'" size="'.$showsize.'" maxlength="'.$size.'" value="'.$value.'"'.($moreparam?$moreparam:'').'>';
-        }
-        elseif ($type == 'text')
-        {
-        	require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
-        	$doleditor=new DolEditor('options_'.$key,$value,'',200,'dolibarr_notes','In',false,false,! empty($conf->fckeditor->enabled) && $conf->global->FCKEDITOR_ENABLE_SOCIETE,5,100);
-        	$out=$doleditor->Create(1);
-        }
-        elseif ($type == 'boolean')
-        {
-        	$checked='';
-        	if (!empty($value)) {
-        		$checked=' checked="checked" value="1" ';
-        	} else {
-        		$checked=' value="1" ';
-        	}
-        	$out='<input type="checkbox" name="options_'.$key.'" '.$checked.' '.($moreparam?$moreparam:'').'>';
-        }
-        elseif ($type == 'mail')
-        {
-        	$out='<input type="text" name="options_'.$key.'" size="32" value="'.$value.'">';
-        }
-        elseif ($type == 'phone')
-        {
-        	$out='<input type="text" name="options_'.$key.'"  size="20" value="'.$value.'">';
-        }
-        elseif ($type == 'price')
-        {
-        	$out='<input type="text" name="options_'.$key.'"  size="6" value="'.price($value).'"> '.$langs->getCurrencySymbol($conf->currency);
-        }
-        elseif ($type == 'select')
-        {
-        	$out='<select name="options_'.$key.'">';
-        	foreach ($param['options'] as $key=>$val )
-        	{
-        		$out.='<option value="'.$key.'"';
-        		$out.= ($value==$key?'selected="selected"':'');
-        		$out.='>'.$val.'</option>';
-        	}
-        	$out.='</select>';
-        }
-        elseif ($type == 'checkbox')
-        {
-        	$out='';
-        	$value_arr=explode(',',$value);
-
-        	foreach ($param['options'] as $keyopt=>$val )
-        	{
-        		
-        		$out.='<input type="checkbox" name="options_'.$key.'[]"';
-        		$out.=' value="'.$keyopt.'"';
-        		
-        		if ((is_array($value_arr)) && in_array($keyopt,$value_arr)) {
-        			$out.= 'checked="checked"';
-        		}else {
-        			$out.='';
-        		}
-        		
-        		$out.='/>'.$val.'<br>';
-        	}
-        }
-        elseif ($type == 'radio')
-        {
-        	$out='';
-        	foreach ($param['options'] as $keyopt=>$val )
-        	{
-        		$out.='<input type="radio" name="options_'.$key.'"';
-        		$out.=' value="'.$keyopt.'"';
-        		$out.= ($value==$keyopt?'checked="checked"':'');
-        		$out.='/>'.$val.'<br>';
-        	}
-        }
-        /* Add comments
-	    if ($type == 'date') $out.=' (YYYY-MM-DD)';
-        elseif ($type == 'datetime') $out.=' (YYYY-MM-DD HH:MM:SS)';
-        */
-	    return $out;
+		{
+			$tmp=explode(',',$size);
+			$newsize=$tmp[0];
+			if(!class_exists('Form'))
+				require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
+			$formstat = new Form($db);
+
+			$showtime = in_array($type,array('datetime')) ? 1 : 0;
+			// Do not show current date when field not required (see select_date() method)
+			if(!$required && $value == '')
+				$value = '-1';
+
+			$out = $formstat->select_date($value, 'options_'.$key, $showtime, $showtime, $required, '', 1, 1, 1, 0, 1);
+			//$out='<input type="text" name="options_'.$key.'" size="'.$showsize.'" maxlength="'.$newsize.'" value="'.$value.'"'.($moreparam?$moreparam:'').'>';
+		}
+		elseif (in_array($type,array('int','double')))
+		{
+			$tmp=explode(',',$size);
+			$newsize=$tmp[0];
+			$out='<input type="text" name="options_'.$key.'" size="'.$showsize.'" maxlength="'.$newsize.'" value="'.$value.'"'.($moreparam?$moreparam:'').'>';
+		}
+		elseif ($type == 'varchar')
+		{
+			$out='<input type="text" name="options_'.$key.'" size="'.$showsize.'" maxlength="'.$size.'" value="'.$value.'"'.($moreparam?$moreparam:'').'>';
+		}
+		elseif ($type == 'text')
+		{
+			require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
+			$doleditor=new DolEditor('options_'.$key,$value,'',200,'dolibarr_notes','In',false,false,! empty($conf->fckeditor->enabled) && $conf->global->FCKEDITOR_ENABLE_SOCIETE,5,100);
+			$out=$doleditor->Create(1);
+		}
+		elseif ($type == 'boolean')
+		{
+			$checked='';
+			if (!empty($value)) {
+				$checked=' checked="checked" value="1" ';
+			} else {
+				$checked=' value="1" ';
+			}
+			$out='<input type="checkbox" name="options_'.$key.'" '.$checked.' '.($moreparam?$moreparam:'').'>';
+		}
+		elseif ($type == 'mail')
+		{
+			$out='<input type="text" name="options_'.$key.'" size="32" value="'.$value.'">';
+		}
+		elseif ($type == 'phone')
+		{
+			$out='<input type="text" name="options_'.$key.'"  size="20" value="'.$value.'">';
+		}
+		elseif ($type == 'price')
+		{
+			$out='<input type="text" name="options_'.$key.'"  size="6" value="'.price($value).'"> '.$langs->getCurrencySymbol($conf->currency);
+		}
+		elseif ($type == 'select')
+		{
+			$out='<select name="options_'.$key.'">';
+			foreach ($param['options'] as $key=>$val )
+			{
+				$out.='<option value="'.$key.'"';
+				$out.= ($value==$key?'selected="selected"':'');
+				$out.='>'.$val.'</option>';
+			}
+			$out.='</select>';
+		}
+		elseif ($type == 'sellist')
+		{
+			$out='<select name="options_'.$key.'">';
+
+			$InfoFieldList = explode(":", $param);
+
+			// 0 1 : tableName
+			// 1 2 : label field name Nom du champ contenant le libelle
+			// 2 3 : key fields name (if differ of rowid)
+
+			$keyList='rowid';
+
+			if (count($InfoFieldList)==3)
+				$keyList=$InfoFieldList[2].' as rowid';
+
+			$sql = 'SELECT '.$keyList.', '.$InfoFieldList[1];
+			$sql.= ' FROM '.MAIN_DB_PREFIX .$InfoFieldList[0];
+
+			$resql = $this->db->query($sql);
+
+			if ($resql)
+			{
+				$out.='<option value="0">&nbsp;</option>';
+				$num = $this->db->num_rows($resql);
+				$i = 0;
+				if ($num)
+				{
+					while ($i < $num)
+					{
+						$obj = $this->db->fetch_object($resql);
+						$labeltoshow=dol_trunc($obj->$InfoFieldList[1],18);
+						if ($value==$obj->rowid)
+						{
+							$out.='<option value="'.$obj->rowid.'" selected="selected">'.$labeltoshow.'</option>';
+						}
+						else
+						{
+							$out.='<option value="'.$obj->rowid.'" >'.$labeltoshow.'</option>';
+						}
+						$i++;
+					}
+				}
+				$this->db->free();
+			}
+			$out.='</select>';
+		}
+		elseif ($type == 'checkbox')
+		{
+			$out='';
+			$value_arr=explode(',',$value);
+
+			foreach ($param['options'] as $keyopt=>$val )
+			{
+
+				$out.='<input type="checkbox" name="options_'.$key.'[]"';
+				$out.=' value="'.$keyopt.'"';
+
+				if ((is_array($value_arr)) && in_array($keyopt,$value_arr)) {
+					$out.= 'checked="checked"';
+				}else {
+					$out.='';
+				}
+
+				$out.='/>'.$val.'<br>';
+			}
+		}
+		elseif ($type == 'radio')
+		{
+			$out='';
+			foreach ($param['options'] as $keyopt=>$val )
+			{
+				$out.='<input type="radio" name="options_'.$key.'"';
+				$out.=' value="'.$keyopt.'"';
+				$out.= ($value==$keyopt?'checked="checked"':'');
+				$out.='/>'.$val.'<br>';
+			}
+		}
+		/* Add comments
+		 if ($type == 'date') $out.=' (YYYY-MM-DD)';
+		elseif ($type == 'datetime') $out.=' (YYYY-MM-DD HH:MM:SS)';
+		*/
+		return $out;
 	}
 
-    /**
-     * Return HTML string to put an output field into a page
-     *
-     * @param   string	$key            Key of attribute
-     * @param   string	$value          Value to show
-     * @param	string	$moreparam		More param
-     * @return	string					Formated value
-     */
-    function showOutputField($key,$value,$moreparam='')
-    {
+	/**
+	 * Return HTML string to put an output field into a page
+	 *
+	 * @param   string	$key            Key of attribute
+	 * @param   string	$value          Value to show
+	 * @param	string	$moreparam		More param
+	 * @return	string					Formated value
+	 */
+	function showOutputField($key,$value,$moreparam='')
+	{
 		global $conf,$langs;
 
-        $label=$this->attribute_label[$key];
-        $type=$this->attribute_type[$key];
-        $size=$this->attribute_size[$key];
-        $elementtype=$this->attribute_elementtype[$key];
-        $unique=$this->attribute_unique[$key];
-        $required=$this->attribute_required[$key];
-        $params=$this->attribute_param[$key];
-        if ($type == 'date')
-        {
-            $showsize=10;
-            $value=dol_print_date($value,'day');
-        }
-        elseif ($type == 'datetime')
-        {
-            $showsize=19;
-            $value=dol_print_date($value,'dayhour');
-        }
-        elseif ($type == 'int')
-        {
-            $showsize=10;
-        }
-        elseif ($type == 'boolean')
-        {
-        	$checked='';
-        	if (!empty($value)) {
-        		$checked=' checked="checked" ';
-        	}
-        	$value='<input type="checkbox" '.$checked.' '.($moreparam?$moreparam:'').' readonly="readonly">';
-        }
-        elseif ($type == 'mail')
-        {
-        	$value=dol_print_email($value);
-        }
-        elseif ($type == 'phone')
-        {
-        	$value=dol_print_phone($value);
-        }
-        elseif ($type == 'price')
-        {
-        	$value=price($value).' '.$langs->getCurrencySymbol($conf->currency);
-        }
-        elseif ($type == 'select')
-        {
-        	$value=$params['options'][$value];
-        }
-        elseif ($type == 'radio')
-        {
-        	$value=$params['options'][$value];
-        }
-        elseif ($type == 'checkbox')
-        {
-        	$value_arr=explode(',',$value);
-        	$value='';
-        	if (is_array($value_arr)) 
-        	{
-	        	foreach ($value_arr as $keyval=>$valueval) {
-	        		$value.=$params['options'][$valueval].'<br>';
-	        	}
-        	}
-        }
-        else
-        {
-            $showsize=round($size);
-            if ($showsize > 48) $showsize=48;
-        }
-        //print $type.'-'.$size;
-        $out=$value;
-        return $out;
-    }
-
-    /**
-     * Return HTML string to print separator extrafield
-     * 
-     * @param   string	$key            Key of attribute
-     * @return string
-     */
-    function showSeparator($key) 
-    {
-    	$out = '<tr class="liste_titre"><td colspan="4"><strong>'.$this->attribute_label[$key].'</strong></td></tr>';
-    	return $out;
-    }
-    
-    /**
-     * Fill array_options array for object by extrafields value (using for data send by forms)
-     *
-     * @param   array	$extralabels    $array of extrafields
-     * @param   object	&$object         object
-     * @return	int						1 if array_options set / 0 if no value
-     */
-    function setOptionalsFromPost($extralabels,&$object)
-    {
-    	global $_POST;
-    	
-    	if (is_array($extralabels))
-    	{
-	    	// Get extra fields
-	    	foreach ($extralabels as $key => $value)
-	    	{
-	    		$key_type = $this->attribute_type[$key];
-	    	
-	    		if (in_array($key_type,array('date','datetime')))
-	    		{
-	    			// Clean parameters
-	    			$value_key=dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]);
-	    		}
-	    		else if (in_array($key_type,array('checkbox')))
-	    		{
-	    			$value_arr=GETPOST("options_".$key);
-	    			$value_key=implode($value_arr,',');
-	    		}
-	    		else 
-	    		{
-	    			$value_key=GETPOST("options_".$key);
-	    		}
-	    		$object->array_options["options_".$key]=$value_key;
-	    	}
-    	
-    		return 1;
-    	}
-    	else {
-    		return 0;
-    	}
-    }
+		$label=$this->attribute_label[$key];
+		$type=$this->attribute_type[$key];
+		$size=$this->attribute_size[$key];
+		$elementtype=$this->attribute_elementtype[$key];
+		$unique=$this->attribute_unique[$key];
+		$required=$this->attribute_required[$key];
+		$params=$this->attribute_param[$key];
+		if ($type == 'date')
+		{
+			$showsize=10;
+			$value=dol_print_date($value,'day');
+		}
+		elseif ($type == 'datetime')
+		{
+			$showsize=19;
+			$value=dol_print_date($value,'dayhour');
+		}
+		elseif ($type == 'int')
+		{
+			$showsize=10;
+		}
+		elseif ($type == 'boolean')
+		{
+			$checked='';
+			if (!empty($value)) {
+				$checked=' checked="checked" ';
+			}
+			$value='<input type="checkbox" '.$checked.' '.($moreparam?$moreparam:'').' readonly="readonly">';
+		}
+		elseif ($type == 'mail')
+		{
+			$value=dol_print_email($value);
+		}
+		elseif ($type == 'phone')
+		{
+			$value=dol_print_phone($value);
+		}
+		elseif ($type == 'price')
+		{
+			$value=price($value).' '.$langs->getCurrencySymbol($conf->currency);
+		}
+		elseif ($type == 'select')
+		{
+			$value=$params['options'][$value];
+		}
+		elseif ($type == 'sellist')
+		{
+			$InfoFieldList = explode(":", $params);
+			$keyList='rowid';
+			if (count($InfoFieldList)==3)
+				$keyList=$InfoFieldList[2];
+
+			$sql = 'SELECT '.$InfoFieldList[1];
+			$sql.= ' FROM '.MAIN_DB_PREFIX .$InfoFieldList[0];
+			$sql.= ' where '.$keyList.'="'.$value.'"';
+
+			$resql = $this->db->query($sql);
+			if ($resql)
+			{
+				$obj = $this->db->fetch_object($resql);
+				$value=$obj->$InfoFieldList[1];
+			}
+		}
+		elseif ($type == 'radio')
+		{
+			$value=$params['options'][$value];
+		}
+		elseif ($type == 'checkbox')
+		{
+			$value_arr=explode(',',$value);
+			$value='';
+			if (is_array($value_arr))
+			{
+				foreach ($value_arr as $keyval=>$valueval) {
+					$value.=$params['options'][$valueval].'<br>';
+				}
+			}
+		}
+		else
+		{
+			$showsize=round($size);
+			if ($showsize > 48) $showsize=48;
+		}
+		//print $type.'-'.$size;
+		$out=$value;
+		return $out;
+	}
+
+	/**
+	 * Return HTML string to print separator extrafield
+	 *
+	 * @param   string	$key            Key of attribute
+	 * @return string
+	 */
+	function showSeparator($key)
+	{
+		$out = '<tr class="liste_titre"><td colspan="4"><strong>'.$this->attribute_label[$key].'</strong></td></tr>';
+		return $out;
+	}
+
+	/**
+	 * Fill array_options array for object by extrafields value (using for data send by forms)
+	 *
+	 * @param   array	$extralabels    $array of extrafields
+	 * @param   object	&$object         object
+	 * @return	int						1 if array_options set / 0 if no value
+	 */
+	function setOptionalsFromPost($extralabels,&$object)
+	{
+		global $_POST;
+			
+		if (is_array($extralabels))
+		{
+			// Get extra fields
+			foreach ($extralabels as $key => $value)
+			{
+				$key_type = $this->attribute_type[$key];
+
+				if (in_array($key_type,array('date','datetime')))
+				{
+					// Clean parameters
+					$value_key=dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]);
+				}
+				else if (in_array($key_type,array('checkbox')))
+				{
+					$value_arr=GETPOST("options_".$key);
+					$value_key=implode($value_arr,',');
+				}
+				else
+				{
+					$value_key=GETPOST("options_".$key);
+				}
+				$object->array_options["options_".$key]=$value_key;
+			}
+
+			return 1;
+		}
+		else {
+			return 0;
+		}
+	}
 }
 ?>
diff --git a/htdocs/core/tpl/admin_extrafields_add.tpl.php b/htdocs/core/tpl/admin_extrafields_add.tpl.php
index 5272c06b31f..44cc7a78bc0 100644
--- a/htdocs/core/tpl/admin_extrafields_add.tpl.php
+++ b/htdocs/core/tpl/admin_extrafields_add.tpl.php
@@ -27,7 +27,7 @@
     		var required = jQuery("#required");
     		var default_value = jQuery("#default_value");
     		<?php
-    		if(GETPOST('type') != "select") 
+    		if((GETPOST('type') != "select") &&  (GETPOST('type') != "sellist"))
     		{
     			print 'jQuery("#value_choice").hide();';
     		}
@@ -48,6 +48,7 @@
     		else if (type == 'boolean') { size.val('').attr('disabled','disabled'); unique.attr('disabled','disabled'); jQuery("#value_choice").hide();}
     		else if (type == 'price') { size.val('').attr('disabled','disabled'); unique.attr('disabled','disabled'); jQuery("#value_choice").hide();}
     		else if (type == 'select') { size.val('').attr('disabled','disabled'); unique.attr('disabled','disabled');  jQuery("#value_choice").show();}
+    		else if (type == 'sellist') { size.val('').attr('disabled','disabled'); unique.attr('disabled','disabled');  jQuery("#value_choice").show();}
     		else if (type == 'checkbox') { size.val('').attr('disabled','disabled'); unique.attr('disabled','disabled');  jQuery("#value_choice").show();}
     		else if (type == 'radio') { size.val('').attr('disabled','disabled'); unique.attr('disabled','disabled');  jQuery("#value_choice").show();}
     		else if (type == 'separate') { size.val('').attr('disabled','disabled'); unique.attr('disabled','disabled');  required.val('').attr('disabled','disabled'); default_value.val('').attr('disabled','disabled'); jQuery("#value_choice").hide();}
@@ -63,6 +64,7 @@
 <form action="<?php echo $_SERVER["PHP_SELF"]; ?>" method="post">
 <input type="hidden" name="token" value="<?php echo $_SESSION['newtoken']; ?>">
 <input type="hidden" name="action" value="add">
+<input type="hidden" name="rowid" value="<?php echo $rowid ?>">
 
 <table summary="listofattributes" class="border centpercent">
 <!-- Type -->
@@ -85,7 +87,7 @@
 <table class="nobordernopadding">
 <tr><td width="30%">
 	<textarea name="param" id="param"><?php echo GETPOST('param'); ?></textarea>
-</td><td><?php print $form->textwithpicto('', $langs->trans("ExtrafieldParamHelp"),1,0)?></td></tr>
+</td><td><?php print $form->textwithpicto('', $langs->trans("ExtrafieldParamHelp".$type),1,0)?></td></tr>
 </table>
 </td>
 
diff --git a/htdocs/core/tpl/admin_extrafields_edit.tpl.php b/htdocs/core/tpl/admin_extrafields_edit.tpl.php
index 181fcd55bbc..d3b06545fa2 100644
--- a/htdocs/core/tpl/admin_extrafields_edit.tpl.php
+++ b/htdocs/core/tpl/admin_extrafields_edit.tpl.php
@@ -44,6 +44,7 @@
 <input type="hidden" name="token" value="<?php echo $_SESSION['newtoken']; ?>">
 <input type="hidden" name="attrname" value="<?php echo $attrname; ?>">
 <input type="hidden" name="action" value="update">
+<input type="hidden" name="rowid" value="<?php echo $rowid ?>">
 
 <table summary="listofattributes" class="border centpercent">
 
@@ -80,7 +81,7 @@ if((($type == 'select') || ($type == 'checkbox') ||(($type == 'radio'))) && is_a
 </td></tr>
 <!--  Value (for select list / radio) -->
 <?php 
-if(($type == 'select') || ($type == 'checkbox') ||(($type == 'radio'))) 
+if(($type == 'select') || ($type == 'sellist') || ($type == 'checkbox') ||(($type == 'radio'))) 
 {
 ?>
 <tr id="value_choice">
@@ -88,7 +89,11 @@ if(($type == 'select') || ($type == 'checkbox') ||(($type == 'radio')))
 	<?php echo $langs->trans("Value"); ?>
 </td>
 <td>
+<table class="nobordernopadding">
+<tr><td width="30%">
 	<textarea name="param" id="param"><?php echo $param_chain; ?></textarea>
+</td><td><?php print $form->textwithpicto('', $langs->trans("ExtrafieldParamHelp".$type),1,0)?></td></tr>
+</table>
 </td>
 </tr>
 <?php 
diff --git a/htdocs/langs/ca_ES/admin.lang b/htdocs/langs/ca_ES/admin.lang
index fc6bdd8bc00..2ef97b1cb26 100644
--- a/htdocs/langs/ca_ES/admin.lang
+++ b/htdocs/langs/ca_ES/admin.lang
@@ -357,7 +357,10 @@ ExtrafieldSelect=Llista de selecció
 ExtrafieldSeparator=Separador
 ExtrafieldCheckBox=Casella de verificació
 ExtrafieldRadio=Botó de selecció excloent
-ExtrafieldParamHelp=La llista ha de ser en forma clau, valor<br><br> per exemple : <br>1,text1<br>2,text2<br>3,text3<br>...
+ExtrafieldParamHelpselect=La llista ha de ser en forma clau, valor<br><br> per exemple : <br>1,text1<br>2,text2<br>3,text3<br>...
+ExtrafieldParamHelpcheckbox=La llista ha de ser en forma clau, valor<br><br> per exemple : <br>1,text1<br>2,text2<br>3,text3<br>...
+ExtrafieldParamHelpradio=La llista ha de ser en forma clau, valor<br><br> per exemple : <br>1,text1<br>2,text2<br>3,text3<br>...
+ExtrafieldParamHelpsellist=La llista ha de ser del table<br><br> per exemple : <br>table:label:(code)<br>
 LibraryToBuildPDF=Llibreria usada per a la creació d'arxius PDF
 WarningUsingFPDF=Atenció: El seu arxiu <b>conf.php</b> conté la directiva <b>dolibarr_pdf_force_fpdf=1</b>. Això fa que s'usi la llibreria FPDF per generar els seus arxius PDF. Aquesta llibreria és antiga i no cobreix algunes funcionalitats (Unicode, transparència d'imatges, idiomes ciríl · lics, àrabs o asiàtics, etc.), Pel que pot tenir problemes en la generació dels PDF.<br> Per resoldre-ho, i disposar d'un suport complet de PDF, pot descarregar la <a href="http://www.tcpdf.org/" target="_blank"> llibreria TCPDF </a>, i a continuació comentar o eliminar la línia <b>$dolibarr_pdf_force_fpdf=1</b>, i afegir al seu lloc <b>$dolibarr_lib_TCPDF_PATH='ruta_a_TCPDF'</b>
 LocalTaxDesc=Alguns països apliquen 2 o 3 taxes a cada línia de factura. Si és el cas, escolliu el tipus de la segona i tercera taxa i el seu valor. Els possibles tipus són: <br> 1: taxa local aplicable a productes i serveis sense IVA (IVA no s'aplica a la taxa local) <br> 2: taxa local s'aplica a productes i serveis abans de l'IVA (IVA es calcula sobre import + taxa local) <br> 3: taxa local s'aplica a productes sense IVA (IVA no s'aplica a la taxa local) <br> 4: taxa local s'aplica a productes abans de l'IVA (IVA es calcula sobre l'import + taxa local) <br> 5: taxa local s'aplica a serveis sense IVA (IVA no s'aplica a la taxa local) <br> 6: taxa local s'aplica a serveis abans de l'IVA (IVA es calcula sobre import + taxa local)
diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
index e73e752fb21..46d893c3984 100644
--- a/htdocs/langs/en_US/admin.lang
+++ b/htdocs/langs/en_US/admin.lang
@@ -360,7 +360,10 @@ ExtrafieldSelect = Select list
 ExtrafieldSeparator=Separator
 ExtrafieldCheckBox=Checkbox
 ExtrafieldRadio=Radio button
-ExtrafieldParamHelp=Parameters list have to be like key,value<br><br> for exemple : <br>1,value1<br>2,value2<br>3,value3<br>... 
+ExtrafieldParamHelpselect=Parameters list have to be like key,value<br><br> for exemple : <br>1,value1<br>2,value2<br>3,value3<br>...
+ExtrafieldParamHelpcheckbox=Parameters list have to be like key,value<br><br> for exemple : <br>1,value1<br>2,value2<br>3,value3<br>...
+ExtrafieldParamHelpradio=Parameters list have to be like key,value<br><br> for exemple : <br>1,value1<br>2,value2<br>3,value3<br>...
+ExtrafieldParamHelpsellist=Parameters list have come from table<br><br> for exemple : <br>c_typent:libelle:id<br> 
 LibraryToBuildPDF=Library used to build PDF
 WarningUsingFPDF=Warning: Your <b>conf.php</b> contains directive <b>dolibarr_pdf_force_fpdf=1</b>. This means you use the FPDF library to generate PDF files. This library is old and does not support a lot of features (Unicode, image transparency, cyrillic, arab and asiatic languages, ...), so you may experience errors during PDF generation.<br>To solve this and have a full support of PDF generation, please download <a href="http://www.tcpdf.org/" target="_blank">TCPDF library</a>, then comment or remove the line <b>$dolibarr_pdf_force_fpdf=1</b>, and add instead <b>$dolibarr_lib_TCPDF_PATH='path_to_TCPDF_dir'</b>   
 LocalTaxDesc=Some countries apply 2 or 3 taxes on each invoice line. If this is the case, choose type for second and third tax and its rate. Possible type are:<br>1 : local tax apply on products and services without vat (vat is not applied on local tax)<br>2 : local tax apply on products and services before vat (vat is calculated on amount + localtax)<br>3 : local tax apply on products without vat (vat is not applied on local tax)<br>4 : local tax apply on products before vat (vat is calculated on amount + localtax)<br>5 : local tax apply on services without vat (vat is not applied on local tax)<br>6 : local tax apply on services before vat (vat is calculated on amount + localtax)
diff --git a/htdocs/langs/es_ES/admin.lang b/htdocs/langs/es_ES/admin.lang
index ec45e7eb6a9..0f2083af780 100644
--- a/htdocs/langs/es_ES/admin.lang
+++ b/htdocs/langs/es_ES/admin.lang
@@ -357,7 +357,10 @@ ExtrafieldSelect=Lista de selección
 ExtrafieldSeparator=Separador
 ExtrafieldCheckBox=Casilla de verificación
 ExtrafieldRadio=Botón de selección excluyente
-ExtrafieldParamHelp=La lista debe ser en forma llave,valor<br><br> por ejemplo : <br>1,texto1<br>2,texto2<br>3,texto3<br>...
+ExtrafieldParamHelpselect=La llista ha de ser en forma clau, valor<br><br> per exemple : <br>1,text1<br>2,text2<br>3,text3<br>...
+ExtrafieldParamHelpcheckbox=La llista ha de ser en forma clau, valor<br><br> per exemple : <br>1,text1<br>2,text2<br>3,text3<br>...
+ExtrafieldParamHelpradio=La llista ha de ser en forma clau, valor<br><br> per exemple : <br>1,text1<br>2,text2<br>3,text3<br>...
+ExtrafieldParamHelpsellist=La llista ha de ser del table<br><br> per exemple : <br>table:label:(code)<br>
 LibraryToBuildPDF=Librería usada para la creación de archivos PDF
 WarningUsingFPDF=Atención: Su archivo <b>conf.php</b> contiene la directiva <b>dolibarr_pdf_force_fpdf=1</b>. Esto hace que se use la librería FPDF para generar sus archivos PDF. Esta librería es antigua y no cubre algunas funcionalidades (Unicode, transparencia de imágenes, idiomas cirílicos, árabes o asiáticos, etc.), por lo que puede tener problemas en la generación de los PDF.<br>Para resolverlo, y disponer de un soporte completo de PDF, puede descargar la <a href="http://www.tcpdf.org/" target="_blank">librería TCPDF</a> , y a continuación comentar o eliminar la línea <b>$dolibarr_pdf_force_fpdf=1</b>, y añadir en su lugar <b>$dolibarr_lib_TCPDF_PATH='ruta_a_TCPDF'</b>   
 LocalTaxDesc=Algunos países aplican 2 o 3 tasas a cada línea de factura. Si es el caso, escoja el tipo de la segunda y tercera tasa y su valor. Los posibles tipos son:<br>1 : tasa local aplicable a productos y servicios sin IVA (IVA no se aplica en la tasa local)<br>2 : tasa local se aplica a productos y servicios antes del IVA (IVA se calcula sobre importe+tasa local)<br>3 : tasa local se aplica a productos sin IVA (IVA no se aplica en la tasa local)<br>4 : tasa local se aplica a productos antes del IVA (IVA se calcula sobre el importe+tasa local)<br>5 : tasa local se aplica a servicios sin IVA (IVA no se aplica a la tasa local)<br>6 : tasa local se aplica a servicios antes del IVA (IVA se calcula sobre importe + tasa local)
diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang
index d1bc47fb624..669ff93ae83 100644
--- a/htdocs/langs/fr_FR/admin.lang
+++ b/htdocs/langs/fr_FR/admin.lang
@@ -357,7 +357,10 @@ ExtrafieldSelect = Liste de sélection
 ExtrafieldSeparator = Séparateur de champ
 ExtrafieldCheckBox=Case à cocher
 ExtrafieldRadio=Case d'option
-ExtrafieldParamHelp=La liste doit être de la forme clef,valeur<br><br> par exemple : <br>1,valeur1<br>2,valeur2<br>3,valeur3<br>...
+ExtrafieldParamHelpselect=La liste doit être de la forme clef,valeur<br><br> par exemple : <br>1,valeur1<br>2,valeur2<br>3,valeur3<br>...
+ExtrafieldParamHelpcheckbox=La liste doit être de la forme clef,valeur<br><br> par exemple : <br>1,valeur1<br>2,valeur2<br>3,valeur3<br>...
+ExtrafieldParamHelpradio=La liste doit être de la forme clef,valeur<br><br> par exemple : <br>1,valeur1<br>2,valeur2<br>3,valeur3<br>...
+ExtrafieldParamHelpsellist=La liste vient d'une table<br><br> par exemple : <br>c_typent:libelle:id<br>
 LibraryToBuildPDF=Bibliothèque utilisée pour la génération des PDF
 WarningUsingFPDF=Attention: Votre fichier <b>conf.php</b> contient la directive <b>dolibarr_pdf_force_fpdf=1</b>. Cela signifie que vous utilisez la librairie FPDF pour générer vos fichiers PDF. Cette librairie est ancienne et ne couvre pas de nombreuses fonctionnalitée (Unicode, transparence des images, langues cyrillic, arabes ou asiatiques...), aussi vous pouvez rencontrez des problèmes durant la génération des PDF.<br>Pour résoudre cela et avoir un support complet de PDF, vous pouvez télécharger la <a href="http://www.tcpdf.org/" target="_blank">librairie TCPDF</a> puis commenter ou supprimer la ligne <b>$dolibarr_pdf_force_fpdf=1</b>, et ajouter à la place <b>$dolibarr_lib_TCPDF_PATH='chemin_vers_TCPDF'</b>   
 LocalTaxDesc=Certains pays appliquent 2 voir 3 taux sur chaque ligne de facture. Si c'est le cas, choisissez le type du deuxième et troisième taux et sa valeur. Les types possibles sont:<br>1 : taxe locale sur les produits et services hors tva (la tva n'est pas appliquée sur la taxe locale)<br>2 : taxe locale sur les produits et services avant tva (la tva est appliquée sur le montant + la taxe locale)<br>3 : taxe locale uniquement sur les produits hors tva (la tva n'est pas appliquée sur la taxe locale)<br>4 : taxe locale uniquement sur les produits avant tva (la tva est appliquée sur le montant + la taxe locale)<br>5 : taxe locale uniquement sur les services hors tva (la tva n'est pas appliquée sur la taxe locale)<br>6 : taxe locale uniquement sur les service avant tva (la tva est appliquée sur le montant + la taxe locale)
-- 
GitLab