diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
index 0693b3dd336..50ccf362de6 100644
--- a/htdocs/core/class/commonobject.class.php
+++ b/htdocs/core/class/commonobject.class.php
@@ -4352,6 +4352,12 @@ abstract class CommonObject
$this->array_options[$key] = null;
}
break;
+ /*case 'select': // Not required, we chosed value='0' for undefined values
+ if ($value=='-1')
+ {
+ $this->array_options[$key] = null;
+ }
+ break;*/
case 'price':
$this->array_options[$key] = price2num($this->array_options[$key]);
break;
@@ -4485,6 +4491,12 @@ abstract class CommonObject
$this->array_options["options_".$key] = null;
}
break;
+ /*case 'select': // Not required, we chosed value='0' for undefined values
+ if ($value=='-1')
+ {
+ $this->array_options[$key] = null;
+ }
+ break;*/
case 'price':
$this->array_options["options_".$key] = price2num($this->array_options["options_".$key]);
break;
diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php
index 3fcb909fc51..a66648df2c2 100644
--- a/htdocs/core/class/extrafields.class.php
+++ b/htdocs/core/class/extrafields.class.php
@@ -348,7 +348,7 @@ class ExtraFields
$sql .= " " . $user->id . ",";
$sql .= "'" . $this->db->idate(dol_now()) . "'";
$sql.=')';
-
+
dol_syslog(get_class($this)."::create_label", LOG_DEBUG);
if ($this->db->query($sql))
{
@@ -721,8 +721,8 @@ class ExtraFields
{
$array_name_label[$tab->name]=$tab->label;
}
-
-
+
+
// Old usage
$this->attribute_type[$tab->name]=$tab->type;
@@ -740,8 +740,8 @@ class ExtraFields
$this->attribute_list[$tab->name]=$tab->list;
$this->attribute_hidden[$tab->name]=$tab->ishidden;
$this->attribute_entityid[$tab->name]=$tab->entity;
-
-
+
+
// New usage
$this->attributes[$tab->elementtype]['type'][$tab->name]=$tab->type;
@@ -759,8 +759,8 @@ class ExtraFields
$this->attributes[$tab->elementtype]['list'][$tab->name]=$tab->list;
$this->attributes[$tab->elementtype]['ishidden'][$tab->name]=$tab->ishidden;
$this->attributes[$tab->elementtype]['entityid'][$tab->name]=$tab->entity;
-
-
+
+
if (!empty($conf->multicompany->enabled)) {
$sql_entity_name='SELECT label FROM '.MAIN_DB_PREFIX.'entity WHERE rowid='.$tab->entity;
$resql_entity_name=$this->db->query($sql_entity_name);
@@ -944,10 +944,10 @@ class ExtraFields
$out.='';
foreach ($param['options'] as $key => $val)
{
- if ($key == '') continue;
+ if ((string) $key == '') continue;
list($val, $parent) = explode('|', $val);
$out.='';
}
diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
index ef2bcbeffb3..7e42e143b6a 100644
--- a/htdocs/core/class/html.form.class.php
+++ b/htdocs/core/class/html.form.class.php
@@ -5080,7 +5080,7 @@ class Form
* @param string $htmlname Name of html select area. Must start with "multi" if this is a multiselect
* @param array $array Array (key => value)
* @param string|string[] $id Preselected key or preselected keys for multiselect
- * @param int $show_empty 0 no empty value allowed, 1 or string to add an empty value into list (value is '' or ' ' if 1), <0 to add an empty value with key that is this value.
+ * @param int|string $show_empty 0 no empty value allowed, 1 or string to add an empty value into list (key is -1 and value is '' or ' ' if 1, key is -1 and value is text if string), <0 to add an empty value with key that is this value.
* @param int $key_in_label 1 to show key into label with format "[key] value"
* @param int $value_as_key 1 to use value as key
* @param string $moreparam Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index 189b80b4abd..7d654104257 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -6264,7 +6264,7 @@ function natural_search($fields, $value, $mode=0, $nofirstand=0)
$newres .= $db->escape($tmpcrit2);
$newres .= $tmpafter;
$newres .= "'";
- if (empty($tmpcrit2))
+ if ($tmpcrit2 == '')
{
$newres .= ' OR ' . $field . " IS NULL";
}
diff --git a/htdocs/install/mysql/migration/repair.sql b/htdocs/install/mysql/migration/repair.sql
index e275d982da4..cd55b7b38e2 100755
--- a/htdocs/install/mysql/migration/repair.sql
+++ b/htdocs/install/mysql/migration/repair.sql
@@ -152,7 +152,8 @@ delete from llx_categorie where fk_parent not in (select rowid from tmp_categori
drop table tmp_categorie;
-- Fix: delete orphelin category.
delete from llx_categorie_product where fk_categorie not in (select rowid from llx_categorie where type = 0);
-delete from llx_categorie_societe where fk_categorie not in (select rowid from llx_categorie where type in (1, 2));
+delete from llx_categorie_fournisseur where fk_categorie not in (select rowid from llx_categorie where type = 1);
+delete from llx_categorie_societe where fk_categorie not in (select rowid from llx_categorie where type = 2);
delete from llx_categorie_member where fk_categorie not in (select rowid from llx_categorie where type = 3);
delete from llx_categorie_contact where fk_categorie not in (select rowid from llx_categorie where type = 4);
delete from llx_categorie_project where fk_categorie not in (select rowid from llx_categorie where type = 5);
diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
index 1107cf1bda9..a8e373518d2 100644
--- a/htdocs/langs/en_US/admin.lang
+++ b/htdocs/langs/en_US/admin.lang
@@ -403,11 +403,11 @@ ExtrafieldCheckBoxFromList=Checkboxes from table
ExtrafieldLink=Link to an object
ComputedFormula=Computed field
ComputedFormulaDesc=You can enter here a formula using other properties of object or any PHP coding to get a dynamic computed value. You can use any PHP compatible formulas including the "?" condition operator, and following global object: $db, $conf, $langs, $mysoc, $user, $object.
WARNING: Only some properties of $object may be available. If you need a properties not loaded, just fetch yourself the object into your formula like in the second example.
Using a computed field means you can't enter yourself any value from interface. Also, if there is a syntax error, the formula may return nothing.
Example of formula:
$object->id < 10 ? round($object->id / 2, 2) : ($object->id + 2 * $user->id) * (int) substr($mysoc->zip, 1, 2)
Example to reload object
(($reloadedobj = new Societe($db)) && ($reloadedobj->fetch($obj->id ? $obj->id : ($obj->rowid ? $obj->rowid : $object->id)) > 0)) ? $reloadedobj->array_options['options_extrafieldkey'] * $reloadedobj->capital / 5 : '-1'
Other example of formula to force load of object and its parent object:
(($reloadedobj = new Task($db)) && ($reloadedobj->fetch($object->id) > 0) && ($secondloadedobj = new Project($db)) && ($secondloadedobj->fetch($reloadedobj->fk_project) > 0)) ? $secondloadedobj->ref : 'Parent project not found'
-ExtrafieldParamHelpselect=Parameters list have to be like key,value
for example :
1,value1
2,value2
3,value3
...
In order to have the list depending on another complementary attribute list :
1,value1|options_parent_list_code:parent_key
2,value2|options_parent_list_code:parent_key
In order to have the list depending on another list :
1,value1|parent_list_code:parent_key
2,value2|parent_list_code:parent_key
-ExtrafieldParamHelpcheckbox=Parameters list have to be like key,value
for example :
1,value1
2,value2
3,value3
...
-ExtrafieldParamHelpradio=Parameters list have to be like key,value
for example :
1,value1
2,value2
3,value3
...
-ExtrafieldParamHelpsellist=Parameters list comes from a table
Syntax : table_name:label_field:id_field::filter
Example : c_typent:libelle:id::filter
filter can be a simple test (eg active=1) to display only active value
You can also use $ID$ in filter witch is the current id of current object
To do a SELECT in filter use $SEL$
if you want to filter on extrafields use syntax extra.fieldcode=... (where field code is the code of extrafield)
In order to have the list depending on another complementary attribute list:
c_typent:libelle:id:options_parent_list_code|parent_column:filter
In order to have the list depending on another list:
c_typent:libelle:id:parent_list_code|parent_column:filter
-ExtrafieldParamHelpchkbxlst=Parameters list comes from a table
Syntax : table_name:label_field:id_field::filter
Example : c_typent:libelle:id::filter
filter can be a simple test (eg active=1) to display only active value
You can also use $ID$ in filter witch is the current id of current object
To do a SELECT in filter use $SEL$
if you want to filter on extrafields use syntax extra.fieldcode=... (where field code is the code of extrafield)
In order to have the list depending on another complementary attribute list :
c_typent:libelle:id:options_parent_list_code|parent_column:filter
In order to have the list depending on another list:
c_typent:libelle:id:parent_list_code|parent_column:filter
+ExtrafieldParamHelpselect=List of values must be lines with format key,value (where key can't be '0')
for example :
1,value1
2,value2
code3,value3
...
In order to have the list depending on another complementary attribute list :
1,value1|options_parent_list_code:parent_key
2,value2|options_parent_list_code:parent_key
In order to have the list depending on another list :
1,value1|parent_list_code:parent_key
2,value2|parent_list_code:parent_key
+ExtrafieldParamHelpcheckbox=List of values must be lines with format key,value (where key can't be '0')
for example :
1,value1
2,value2
3,value3
...
+ExtrafieldParamHelpradio=List of values must be lines with format key,value (where key can't be '0')
for example :
1,value1
2,value2
3,value3
...
+ExtrafieldParamHelpsellist=List of values comes from a table
Syntax : table_name:label_field:id_field::filter
Example : c_typent:libelle:id::filter
filter can be a simple test (eg active=1) to display only active value
You can also use $ID$ in filter witch is the current id of current object
To do a SELECT in filter use $SEL$
if you want to filter on extrafields use syntax extra.fieldcode=... (where field code is the code of extrafield)
In order to have the list depending on another complementary attribute list:
c_typent:libelle:id:options_parent_list_code|parent_column:filter
In order to have the list depending on another list:
c_typent:libelle:id:parent_list_code|parent_column:filter
+ExtrafieldParamHelpchkbxlst=List of values comes from a table
Syntax : table_name:label_field:id_field::filter
Example : c_typent:libelle:id::filter
filter can be a simple test (eg active=1) to display only active value
You can also use $ID$ in filter witch is the current id of current object
To do a SELECT in filter use $SEL$
if you want to filter on extrafields use syntax extra.fieldcode=... (where field code is the code of extrafield)
In order to have the list depending on another complementary attribute list :
c_typent:libelle:id:options_parent_list_code|parent_column:filter
In order to have the list depending on another list:
c_typent:libelle:id:parent_list_code|parent_column:filter
ExtrafieldParamHelplink=Parameters must be ObjectName:Classpath
Syntax : ObjectName:Classpath
Example : Societe:societe/class/societe.class.php
LibraryToBuildPDF=Library used for PDF generation
WarningUsingFPDF=Warning: Your conf.php contains directive dolibarr_pdf_force_fpdf=1. 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.
To solve this and have a full support of PDF generation, please download TCPDF library, then comment or remove the line $dolibarr_pdf_force_fpdf=1, and add instead $dolibarr_lib_TCPDF_PATH='path_to_TCPDF_dir'
diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php
index 81e0612cea5..d599c563912 100644
--- a/htdocs/modulebuilder/template/myobject_list.php
+++ b/htdocs/modulebuilder/template/myobject_list.php
@@ -228,7 +228,7 @@ foreach ($search_array_options as $key => $val)
$typ=$extrafields->attribute_type[$tmpkey];
$mode=0;
if (in_array($typ, array('int','double','real'))) $mode=1; // Search on a numeric
- if ($val && ( ($crit != '' && ! in_array($typ, array('select'))) || ! empty($crit)))
+ if ($crit != '' && (! in_array($typ, array('select')) || $crit != '0'))
{
$sql .= natural_search('ef.'.$tmpkey, $crit, $mode);
}
diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php
index 94fc46f5734..da2b7612838 100644
--- a/htdocs/societe/list.php
+++ b/htdocs/societe/list.php
@@ -73,7 +73,8 @@ $search_idprof4=trim(GETPOST('search_idprof4'));
$search_idprof5=trim(GETPOST('search_idprof5'));
$search_idprof6=trim(GETPOST('search_idprof6'));
$search_sale=trim(GETPOST("search_sale",'int'));
-$search_categ=trim(GETPOST("search_categ",'int'));
+$search_categ_cus=trim(GETPOST("search_categ_cus",'int'));
+$search_categ_sup=trim(GETPOST("search_categ_sup",'int'));
$search_country=GETPOST("search_country",'intcomma');
$search_type_thirdparty=GETPOST("search_type_thirdparty",'int');
$search_status=GETPOST("search_status",'int');
@@ -220,7 +221,8 @@ if (empty($reshook))
$search_id='';
$search_nom='';
$search_alias='';
- $search_categ=0;
+ $search_categ_cus=0;
+ $search_categ_sup=0;
$search_sale='';
$search_barcode="";
$search_customer_code='';
@@ -389,7 +391,8 @@ $sql.= " state.code_departement as state_code, state.nom as state_name";
// We'll need these fields in order to filter by sale (including the case where the user can only see his prospects)
if ($search_sale) $sql .= ", sc.fk_soc, sc.fk_user";
// We'll need these fields in order to filter by categ
-if ($search_categ) $sql .= ", cs.fk_categorie, cs.fk_soc";
+if ($search_categ_cus) $sql .= ", cc.fk_categorie, cc.fk_soc";
+if ($search_categ_sup) $sql .= ", cs.fk_categorie, cs.fk_soc";
// Add fields from extrafields
foreach ($extrafields->attribute_label as $key => $val) $sql.=($extrafields->attribute_type[$key] != 'separate' ? ",ef.".$key.' as options_'.$key : '');
// Add fields from hooks
@@ -402,7 +405,8 @@ $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as country on (country.rowid = s.
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_typent as typent on (typent.id = s.fk_typent)";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as state on (state.rowid = s.fk_departement)";
// We'll need this table joined to the select in order to filter by categ
-if (! empty($search_categ)) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_".($type=='f'?"fournisseur":"societe")." as cs ON s.rowid = cs.fk_soc"; // We'll need this table joined to the select in order to filter by categ
+if (! empty($search_categ_cus)) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_societe as cc ON s.rowid = cc.fk_soc"; // We'll need this table joined to the select in order to filter by categ
+if (! empty($search_categ_sup)) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_fournisseur as cs ON s.rowid = cs.fk_soc"; // We'll need this table joined to the select in order to filter by categ
$sql.= " ,".MAIN_DB_PREFIX."c_stcomm as st";
// We'll need this table joined to the select in order to filter by sale
if ($search_sale || (!$user->rights->societe->client->voir && !$socid)) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
@@ -413,8 +417,10 @@ if ($socid) $sql.= " AND s.rowid = ".$socid;
if ($search_sale) $sql.= " AND s.rowid = sc.fk_soc"; // Join for the needed table to filter by sale
if (! $user->rights->fournisseur->lire) $sql.=" AND (s.fournisseur <> 1 OR s.client <> 0)"; // client=0, fournisseur=0 must be visible
if ($search_sale) $sql.= " AND sc.fk_user = ".$db->escape($search_sale);
-if ($search_categ > 0) $sql.= " AND cs.fk_categorie = ".$db->escape($search_categ);
-if ($search_categ == -2) $sql.= " AND cs.fk_categorie IS NULL";
+if ($search_categ_cus > 0) $sql.= " AND cc.fk_categorie = ".$db->escape($search_categ_cus);
+if ($search_categ_sup > 0) $sql.= " AND cs.fk_categorie = ".$db->escape($search_categ_sup);
+if ($search_categ_cus == -2) $sql.= " AND cc.fk_categorie IS NULL";
+if ($search_categ_sup == -2) $sql.= " AND cs.fk_categorie IS NULL";
if ($search_all) $sql.= natural_search(array_keys($fieldstosearchall), $search_all);
if (strlen($search_cti)) $sql.= natural_search('s.phone', $search_cti);
@@ -457,8 +463,8 @@ foreach ($search_array_options as $key => $val)
$tmpkey=preg_replace('/search_options_/','',$key);
$typ=$extrafields->attribute_type[$tmpkey];
$mode=0;
- if (in_array($typ, array('int','double'))) $mode=1; // Search on a numeric
- if ($val && ( ($crit != '' && ! in_array($typ, array('select'))) || ! empty($crit)))
+ if (in_array($typ, array('int','double','real'))) $mode=1; // Search on a numeric
+ if ($crit != '' && (! in_array($typ, array('select')) || $crit != '0'))
{
$sql .= natural_search('ef.'.$tmpkey, $crit, $mode);
}
@@ -507,7 +513,8 @@ if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&con
if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit;
if ($search_all != '') $param = "&sall=".urlencode($search_all);
if ($sall != '') $param .= "&sall=".urlencode($sall);
-if ($search_categ > 0) $param.='&search_categ='.urlencode($search_categ);
+if ($search_categ_cus > 0) $param.='&search_categ_cus='.urlencode($search_categ_cus);
+if ($search_categ_sup > 0) $param.='&search_categ_sup='.urlencode($search_categ_sup);
if ($search_sale > 0) $param.='&search_sale='.urlencode($search_sale);
if ($search_id > 0) $param.= "&search_id=".urlencode($search_id);
if ($search_nom != '') $param.= "&search_nom=".urlencode($search_nom);
@@ -594,28 +601,28 @@ if ($search_all)
// Filter on categories
$moreforfilter='';
-if ($type == 'c' || $type == 'p')
-{
+//if ($type == 'c' || $type == 'p')
+//{
if (! empty($conf->categorie->enabled))
{
require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
$moreforfilter.='