From 6a734ea8289bf1f51cfb21e5a84e9344bb4932b7 Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Mon, 9 Sep 2019 16:58:20 +0200 Subject: [PATCH 01/12] NEW add minimum stock filter in load warehoues for product form --- htdocs/expedition/card.php | 8 +- .../product/class/html.formproduct.class.php | 97 ++++++++++++------- 2 files changed, 68 insertions(+), 37 deletions(-) diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index cc05bf686c3..4202607cbd2 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -1262,7 +1262,13 @@ if ($action == 'create') if ($line->fk_product > 0) { print ''; - print $formproduct->selectWarehouses($tmpentrepot_id, 'entl'.$indiceAsked, '', 1, 0, $line->fk_product, '', 1); + + $stockMin = false; + if (empty($conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER)) { + $stockMin = 0; + } + print $formproduct->selectWarehouses($tmpentrepot_id, 'entl'.$indiceAsked, '', 1, 0, $line->fk_product, '', 1, 0, array(), 'minwidth200', '', 1, $stockMin, 'stock DESC, e.ref'); + if ($tmpentrepot_id > 0 && $tmpentrepot_id == $warehouse_id) { //print $stock.' '.$quantityToBeDelivered; diff --git a/htdocs/product/class/html.formproduct.class.php b/htdocs/product/class/html.formproduct.class.php index a0ebda88cd9..e356226dd2f 100644 --- a/htdocs/product/class/html.formproduct.class.php +++ b/htdocs/product/class/html.formproduct.class.php @@ -55,21 +55,24 @@ class FormProduct } - /** - * Load in cache array list of warehouses - * If fk_product is not 0, we do not use cache - * - * @param int $fk_product Add quantity of stock in label for product with id fk_product. Nothing if 0. - * @param string $batch Add quantity of batch stock in label for product with batch name batch, batch name precedes batch_id. Nothing if ''. - * @param string $status warehouse status filter, following comma separated filter options can be used - * 'warehouseopen' = select products from open warehouses, - * 'warehouseclosed' = select products from closed warehouses, - * 'warehouseinternal' = select products from warehouses for internal correct/transfer only - * @param boolean $sumStock sum total stock of a warehouse, default true - * @param array $exclude warehouses ids to exclude - * @return int Nb of loaded lines, 0 if already loaded, <0 if KO - */ - public function loadWarehouses($fk_product = 0, $batch = '', $status = '', $sumStock = true, $exclude = '') + /** + * Load in cache array list of warehouses + * If fk_product is not 0, we do not use cache + * + * @param int $fk_product Add quantity of stock in label for product with id fk_product. Nothing if 0. + * @param string $batch Add quantity of batch stock in label for product with batch name batch, batch name precedes batch_id. Nothing if ''. + * @param string $status warehouse status filter, following comma separated filter options can be used + * 'warehouseopen' = select products from open warehouses, + * 'warehouseclosed' = select products from closed warehouses, + * 'warehouseinternal' = select products from warehouses for internal correct/transfer only + * @param boolean $sumStock sum total stock of a warehouse, default true + * @param string $exclude warehouses ids to exclude + * @param bool|int $stockMin [=false] Value of minimum stock to filter or false not not filter by minimum stock + * @param string $orderBy [='e.ref'] Order by + * @return int Nb of loaded lines, 0 if already loaded, <0 if KO + * @throws Exception + */ + public function loadWarehouses($fk_product = 0, $batch = '', $status = '', $sumStock = true, $exclude = '', $stockMin = false, $orderBy = 'e.ref') { global $conf, $langs; @@ -130,8 +133,26 @@ class FormProduct if(!empty($exclude)) $sql.= ' AND e.rowid NOT IN('.$this->db->escape(implode(',', $exclude)).')'; - if ($sumStock && empty($fk_product)) $sql.= " GROUP BY e.rowid, e.ref, e.description, e.fk_parent"; - $sql.= " ORDER BY e.ref"; + // minimum stock + if ($stockMin !== false) { + if (!empty($fk_product)) { + if (!empty($batch)) { + $sql .= " AND pb.qty > " . $this->db->escape($stockMin); + } else { + $sql .= " AND ps.reel > " . $this->db->escape($stockMin); + } + } + } + + if ($sumStock && empty($fk_product)) { + $sql.= " GROUP BY e.rowid, e.ref, e.description, e.fk_parent"; + + // minimum stock + if ($stockMin !== false) { + $sql .= " HAVING sum(ps.reel) > " . $this->db->escape($stockMin); + } + } + $sql.= " ORDER BY " . $orderBy; dol_syslog(get_class($this).'::loadWarehouses', LOG_DEBUG); $resql = $this->db->query($sql); @@ -192,25 +213,29 @@ class FormProduct /** * Return list of warehouses * - * @param int $selected Id of preselected warehouse ('' for no value, 'ifone'=select value if one value otherwise no value) - * @param string $htmlname Name of html select html - * @param string $filterstatus warehouse status filter, following comma separated filter options can be used - * 'warehouseopen' = select products from open warehouses, - * 'warehouseclosed' = select products from closed warehouses, - * 'warehouseinternal' = select products from warehouses for internal correct/transfer only - * @param int $empty 1=Can be empty, 0 if not - * @param int $disabled 1=Select is disabled - * @param int $fk_product Add quantity of stock in label for product with id fk_product. Nothing if 0. - * @param string $empty_label Empty label if needed (only if $empty=1) - * @param int $showstock 1=Show stock count - * @param int $forcecombo 1=Force combo iso ajax select2 - * @param array $events Events to add to select2 - * @param string $morecss Add more css classes to HTML select - * @param array $exclude Warehouses ids to exclude - * @param int $showfullpath 1=Show full path of name (parent ref into label), 0=Show only ref of current warehouse - * @return string HTML select + * @param string|int $selected Id of preselected warehouse ('' for no value, 'ifone'=select value if one value otherwise no value) + * @param string $htmlname Name of html select html + * @param string $filterstatus warehouse status filter, following comma separated filter options can be used + * 'warehouseopen' = select products from open warehouses, + * 'warehouseclosed' = select products from closed warehouses, + * 'warehouseinternal' = select products from warehouses for internal correct/transfer only + * @param int $empty 1=Can be empty, 0 if not + * @param int $disabled 1=Select is disabled + * @param int $fk_product Add quantity of stock in label for product with id fk_product. Nothing if 0. + * @param string $empty_label Empty label if needed (only if $empty=1) + * @param int $showstock 1=Show stock count + * @param int $forcecombo 1=Force combo iso ajax select2 + * @param array $events Events to add to select2 + * @param string $morecss Add more css classes to HTML select + * @param string $exclude Warehouses ids to exclude + * @param int $showfullpath 1=Show full path of name (parent ref into label), 0=Show only ref of current warehouse + * @param bool|int $stockMin [=false] Value of minimum stock to filter or false not not filter by minimum stock + * @param string $orderBy [='e.ref'] Order by + * @return string HTML select + * + * @throws Exception */ - public function selectWarehouses($selected = '', $htmlname = 'idwarehouse', $filterstatus = '', $empty = 0, $disabled = 0, $fk_product = 0, $empty_label = '', $showstock = 0, $forcecombo = 0, $events = array(), $morecss = 'minwidth200', $exclude = '', $showfullpath = 1) + public function selectWarehouses($selected = '', $htmlname = 'idwarehouse', $filterstatus = '', $empty = 0, $disabled = 0, $fk_product = 0, $empty_label = '', $showstock = 0, $forcecombo = 0, $events = array(), $morecss = 'minwidth200', $exclude = '', $showfullpath = 1, $stockMin = false, $orderBy = 'e.ref') { global $conf,$langs,$user; @@ -218,7 +243,7 @@ class FormProduct $out=''; if (empty($conf->global->ENTREPOT_EXTRA_STATUS)) $filterstatus = ''; - $this->loadWarehouses($fk_product, '', $filterstatus, true, $exclude); + $this->loadWarehouses($fk_product, '', $filterstatus, true, $exclude, $stockMin, $orderBy); $nbofwarehouses=count($this->cache_warehouses); if ($conf->use_javascript_ajax && ! $forcecombo) From 797bab47417ad3f1673b09a0470a25ce6e870f79 Mon Sep 17 00:00:00 2001 From: Abbes Bahfir Date: Wed, 11 Sep 2019 18:42:46 +0100 Subject: [PATCH 02/12] fix: repetition --- htdocs/core/class/ldap.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/ldap.class.php b/htdocs/core/class/ldap.class.php index 1d1a6122288..266b41867e8 100644 --- a/htdocs/core/class/ldap.class.php +++ b/htdocs/core/class/ldap.class.php @@ -609,7 +609,7 @@ class Ldap } if ($result <= 0) { - $this->error = ldap_errno($this->connection)." ".ldap_error($this->connection)." ".$this->error; + $this->error = ldap_errno($this->connection)." ".$this->error; dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR); //print_r($info); return -1; From 5183a1ec7a19cd553fd9fa728a911df3310174b9 Mon Sep 17 00:00:00 2001 From: Abbes Bahfir Date: Wed, 11 Sep 2019 22:45:02 +0100 Subject: [PATCH 03/12] New : Use of posixAccount and posixGroup objectclass for users and groups in LDAP --- htdocs/admin/ldap_groups.php | 8 +++++++ htdocs/admin/ldap_users.php | 33 +++++++++++++++++++++++++++ htdocs/langs/en_US/admin.lang | 7 ++++++ htdocs/langs/fr_FR/admin.lang | 7 ++++++ htdocs/user/class/user.class.php | 18 +++++++++++++-- htdocs/user/class/usergroup.class.php | 5 +++- 6 files changed, 75 insertions(+), 3 deletions(-) diff --git a/htdocs/admin/ldap_groups.php b/htdocs/admin/ldap_groups.php index 450fec88ad0..6dcc26a23e0 100644 --- a/htdocs/admin/ldap_groups.php +++ b/htdocs/admin/ldap_groups.php @@ -58,6 +58,7 @@ if ($action == 'setvalue' && $user->admin) //if (! dolibarr_set_const($db, 'LDAP_GROUP_FIELD_NAME',$_POST["fieldname"],'chaine',0,'',$conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_GROUP_FIELD_DESCRIPTION', GETPOST("fielddescription"), 'chaine', 0, '', $conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_GROUP_FIELD_GROUPMEMBERS', GETPOST("fieldgroupmembers"), 'chaine', 0, '', $conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_FIELD_GROUPID', GETPOST("fieldgroupid"), 'chaine', 0, '', $conf->entity)) $error++; // This one must be after the others $valkey=''; @@ -170,6 +171,13 @@ print ''.$langs->trans("LDAPFieldGroupMembersExample").''; print 'global->LDAP_KEY_GROUPS && $conf->global->LDAP_KEY_GROUPS==$conf->global->LDAP_GROUP_FIELD_GROUPMEMBERS)?' checked':'').">"; print ''; +// Group id +print ''.$langs->trans("LDAPFieldGroupid").''; +print ''; +print ''.$langs->trans("LDAPFieldGroupidExample").''; +print ' '; +print ''; + print ''; print info_admin($langs->trans("LDAPDescValues")); diff --git a/htdocs/admin/ldap_users.php b/htdocs/admin/ldap_users.php index 4148d81f438..394451c9472 100644 --- a/htdocs/admin/ldap_users.php +++ b/htdocs/admin/ldap_users.php @@ -5,6 +5,7 @@ * Copyright (C) 2005 Regis Houssin * Copyright (C) 2006-2011 Laurent Destailleur * Copyright (C) 2011-2016 Juanjo Menent + * Copyright (C) 2019 Abbes Bahfir * * 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 @@ -73,6 +74,10 @@ if ($action == 'setvalue' && $user->admin) if (! dolibarr_set_const($db, 'LDAP_FIELD_DESCRIPTION', GETPOST("fielddescription"), 'chaine', 0, '', $conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_FIELD_SID', GETPOST("fieldsid"), 'chaine', 0, '', $conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_FIELD_TITLE', GETPOST("fieldtitle"), 'chaine', 0, '', $conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_FIELD_GROUPID', GETPOST("fieldgroupid"), 'chaine', 0, '', $conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_FIELD_USERID', GETPOST("fielduserid"), 'chaine', 0, '', $conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_FIELD_HOMEDIRECTORY', GETPOST("fieldhomedirectory"), 'chaine', 0, '', $conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_FIELD_HOMEDIRECTORYPREFIX', GETPOST("fieldhomedirectoryprefix"), 'chaine', 0, '', $conf->entity)) $error++; // This one must be after the others $valkey=''; @@ -301,6 +306,34 @@ print ''.$langs->trans("LDAPFieldSidExample").''; print 'global->LDAP_KEY_USERS && $conf->global->LDAP_KEY_USERS==$conf->global->LDAP_FIELD_SID)?' checked':'').">"; print ''; +// Group id +print ''.$langs->trans("LDAPFieldGroupid").''; +print ''; +print ''.$langs->trans("LDAPFieldGroupidExample").''; +print ' '; +print ''; + +// Userid +print ''.$langs->trans("LDAPFieldUserid").''; +print ''; +print ''.$langs->trans("LDAPFieldUseridExample").''; +print ' '; +print ''; + +// Home Directory +print ''.$langs->trans("LDAPFieldHomedirectory").''; +print ''; +print ''.$langs->trans("LDAPFieldHomedirectoryExample").''; +print ' '; +print ''; + +// Home Directory Prefix +print ''.$langs->trans("LDAPFieldHomedirectoryprefix").''; +print ''; +print ''; +print ' '; +print ''; + print ''; print info_admin($langs->trans("LDAPDescValues")); diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index a8f7f9643ce..3eb9f24112d 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1458,6 +1458,13 @@ LDAPFieldSidExample=Example: objectsid LDAPFieldEndLastSubscription=Date of subscription end LDAPFieldTitle=Job position LDAPFieldTitleExample=Example: title +LDAPFieldGroupid=Group id +LDAPFieldGroupidExample=Exemple : gidnumber +LDAPFieldUserid=User id +LDAPFieldUseridExample=Exemple : uidnumber +LDAPFieldHomedirectory=Home directory prefix +LDAPFieldHomedirectoryExample=Exemple : homedirectory +LDAPFieldHomedirectoryprefix=Home directory prefix LDAPSetupNotComplete=LDAP setup not complete (go on others tabs) LDAPNoUserOrPasswordProvidedAccessIsReadOnly=No administrator or password provided. LDAP access will be anonymous and in read only mode. LDAPDescContact=This page allows you to define LDAP attributes name in LDAP tree for each data found on Dolibarr contacts. diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index 20cdc9175d6..ff684f01cb9 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -1458,6 +1458,13 @@ LDAPFieldSidExample=Exemple : objectsid LDAPFieldEndLastSubscription=Date de fin de validité adhésion LDAPFieldTitle=Poste/fonction LDAPFieldTitleExample=Exemple: title +LDAPFieldGroupid=Groupe id +LDAPFieldGroupidExample=Exemple : gidnumber +LDAPFieldUserid=User id +LDAPFieldUseridExample=Exemple : uidnumber +LDAPFieldHomedirectory=Répertoire d'accueil +LDAPFieldHomedirectoryExample=Exemple : homedirectory +LDAPFieldHomedirectoryprefix=Préfixe du répertoire d'accueil LDAPSetupNotComplete=Configuration LDAP incomplète (à compléter sur les autres onglets) LDAPNoUserOrPasswordProvidedAccessIsReadOnly=Administrateur ou mot de passe non renseigné. Les accès LDAP seront donc anonymes et en lecture seule. LDAPDescContact=Cette page permet de définir le nom des attributs de l'arbre LDAP pour chaque information des contacts Dolibarr. diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 4d78aa1b892..aa4aec74251 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -13,6 +13,7 @@ * Copyright (C) 2018 charlene Benke * Copyright (C) 2018 Nicolas ZABOURI * Copyright (C) 2019 Frédéric France + * Copyright (C) 2019 Abbes Bahfir * * 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 @@ -35,6 +36,7 @@ */ require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php'; +require_once DOL_DOCUMENT_ROOT .'/user/class/usergroup.class.php'; /** * Class to manage Dolibarr users @@ -2655,8 +2657,20 @@ class User extends CommonObject if ($this->phone_mobile) $info["phpgwCellTelephoneNumber"] = $this->phone_mobile; } - return $info; - } + $info[$conf->global->LDAP_FIELD_USERID] = $this->id; + $info[$conf->global->LDAP_FIELD_GROUPID] = '1'; + $usergroup = new UserGroup($this->db); + $groupslist = $usergroup->listGroupsForUser($this->id); + if(!empty($groupslist)){ + foreach ($groupslist as $groupforuser) { + $info[$conf->global->LDAP_FIELD_GROUPID] = $groupforuser->id;//Select first group in list + break; + } + } + $info[$conf->global->LDAP_FIELD_HOMEDIRECTORY]="{$conf->global->LDAP_FIELD_HOMEDIRECTORYPREFIX}/$this->firstname"; + + return $info; + } /** diff --git a/htdocs/user/class/usergroup.class.php b/htdocs/user/class/usergroup.class.php index d51d82c8d13..c0cd4d9227f 100644 --- a/htdocs/user/class/usergroup.class.php +++ b/htdocs/user/class/usergroup.class.php @@ -6,6 +6,7 @@ * Copyright (C) 2014 Juanjo Menent * Copyright (C) 2014 Alexis Algoud * Copyright (C) 2018 Nicolas ZABOURI + * Copyright (C) 2019 Abbes Bahfir * * 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 @@ -978,7 +979,9 @@ class UserGroup extends CommonObject $valueofldapfield[] = $muser->_load_ldap_dn($info2); } $info[$conf->global->LDAP_GROUP_FIELD_GROUPMEMBERS] = (!empty($valueofldapfield)?$valueofldapfield:''); - } + + } + $info[$conf->global->LDAP_FIELD_GROUPID]=$this->id; return $info; } From e5878c105a001d1215a31c121b10caee5452da02 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Wed, 11 Sep 2019 21:48:17 +0000 Subject: [PATCH 04/12] Fixing style errors. --- htdocs/user/class/usergroup.class.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/user/class/usergroup.class.php b/htdocs/user/class/usergroup.class.php index c0cd4d9227f..4e8cdf5824b 100644 --- a/htdocs/user/class/usergroup.class.php +++ b/htdocs/user/class/usergroup.class.php @@ -979,7 +979,6 @@ class UserGroup extends CommonObject $valueofldapfield[] = $muser->_load_ldap_dn($info2); } $info[$conf->global->LDAP_GROUP_FIELD_GROUPMEMBERS] = (!empty($valueofldapfield)?$valueofldapfield:''); - } $info[$conf->global->LDAP_FIELD_GROUPID]=$this->id; return $info; From 195ac8e8f6d70b60495cc6c2b99d4af2465dfab0 Mon Sep 17 00:00:00 2001 From: Abbes Bahfir Date: Thu, 12 Sep 2019 11:18:22 +0100 Subject: [PATCH 05/12] fix : Tests for attributes exsitence in Use of posixAccount and posixGroup objectclass for users and groups in LDAP --- htdocs/user/class/user.class.php | 20 +++++++++++--------- htdocs/user/class/usergroup.class.php | 4 +++- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index aa4aec74251..ae1d9afa062 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -2657,17 +2657,19 @@ class User extends CommonObject if ($this->phone_mobile) $info["phpgwCellTelephoneNumber"] = $this->phone_mobile; } - $info[$conf->global->LDAP_FIELD_USERID] = $this->id; - $info[$conf->global->LDAP_FIELD_GROUPID] = '1'; - $usergroup = new UserGroup($this->db); - $groupslist = $usergroup->listGroupsForUser($this->id); - if(!empty($groupslist)){ - foreach ($groupslist as $groupforuser) { - $info[$conf->global->LDAP_FIELD_GROUPID] = $groupforuser->id;//Select first group in list - break; + if (!empty($conf->global->LDAP_FIELD_USERID))$info[$conf->global->LDAP_FIELD_USERID] = $this->id; + if(!empty($info[$conf->global->LDAP_FIELD_GROUPID])){ + $usergroup = new UserGroup($this->db); + $groupslist = $usergroup->listGroupsForUser($this->id); + $info[$conf->global->LDAP_FIELD_GROUPID] = '1'; + if(!empty($groupslist)){ + foreach ($groupslist as $groupforuser) { + $info[$conf->global->LDAP_FIELD_GROUPID] = $groupforuser->id;//Select first group in list + break; + } } } - $info[$conf->global->LDAP_FIELD_HOMEDIRECTORY]="{$conf->global->LDAP_FIELD_HOMEDIRECTORYPREFIX}/$this->firstname"; + if (!empty($this->firstname) && !empty($conf->global->LDAP_FIELD_HOMEDIRECTORY) && !empty($conf->global->LDAP_FIELD_HOMEDIRECTORYPREFIX)) $info[$conf->global->LDAP_FIELD_HOMEDIRECTORY]="{$conf->global->LDAP_FIELD_HOMEDIRECTORYPREFIX}/$this->firstname"; return $info; } diff --git a/htdocs/user/class/usergroup.class.php b/htdocs/user/class/usergroup.class.php index c0cd4d9227f..f2194b1d8b7 100644 --- a/htdocs/user/class/usergroup.class.php +++ b/htdocs/user/class/usergroup.class.php @@ -981,7 +981,9 @@ class UserGroup extends CommonObject $info[$conf->global->LDAP_GROUP_FIELD_GROUPMEMBERS] = (!empty($valueofldapfield)?$valueofldapfield:''); } - $info[$conf->global->LDAP_FIELD_GROUPID]=$this->id; + if(!empty($info[$conf->global->LDAP_FIELD_GROUPID])){ + $info[$conf->global->LDAP_FIELD_GROUPID]=$this->id; + } return $info; } From 165ee28823dd8eb741d185d58be2a7c9e4eb2a46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 12 Sep 2019 21:48:00 +0200 Subject: [PATCH 06/12] Update .editorconfig editorconfig control the github online editor --- .editorconfig | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index 2df455f0d4f..3e3bd16bb34 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,14 +1,21 @@ -# EditorConfig is awesome: http://EditorConfig.org +# EditorConfig is awesome: https://editorconfig.org # top-most EditorConfig file root = true + # Unix-style newlines with a newline ending every file [*] charset = utf-8 end_of_line = lf insert_final_newline = true + +# PHP PSR-2 Coding Standards +# http://www.php-fig.org/psr/psr-2/ [*.php] indent_style = tab +indent_size = 4 +trim_trailing_whitespace = true +insert_final_newline = true [*.js] indent_style = tab [*.css] From 44fa2e4cd115605654a5ec9a5d82a691a748fae3 Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Fri, 13 Sep 2019 12:23:34 +0200 Subject: [PATCH 07/12] NEW multiselect with checkbox in categories/tags search for product list --- htdocs/product/list.php | 50 ++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/htdocs/product/list.php b/htdocs/product/list.php index e7e8f1e4999..d8d9686ae4a 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -57,7 +57,8 @@ $search_label=GETPOST("search_label", 'alpha'); $search_type = GETPOST("search_type", 'int'); $search_sale = GETPOST("search_sale", 'int'); $search_vatrate=GETPOST("search_vatrate", 'alpha'); -$search_categ = GETPOST("search_categ", 'int'); +$searchCategoryProductOperator = (GETPOST('search_category_product_operator', 'int') ? GETPOST('search_category_product_operator', 'int') : 0); +$searchCategoryProductList = GETPOST('search_category_product_list', 'array'); $search_tosell = GETPOST("search_tosell", 'int'); $search_tobuy = GETPOST("search_tobuy", 'int'); $fourn_id = GETPOST("fourn_id", 'int'); @@ -231,7 +232,8 @@ if (empty($reshook)) $search_ref=""; $search_label=""; $search_barcode=""; - $search_categ=0; + $searchCategoryProductOperator = 0; + $searchCategoryProductList = array(); $search_tosell=""; $search_tobuy=""; $search_vatrate=""; @@ -301,7 +303,7 @@ $reshook=$hookmanager->executeHooks('printFieldListSelect', $parameters); // $sql.=$hookmanager->resPrint; $sql.= ' FROM '.MAIN_DB_PREFIX.'product as p'; if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_extrafields as ef on (p.rowid = ef.fk_object)"; -if (! empty($search_categ) || ! empty($catid)) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_product as cp ON p.rowid = cp.fk_product"; // We'll need this table joined to the select in order to filter by categ +if (!empty($searchCategoryProductList) || !empty($catid)) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_product as cp ON p.rowid = cp.fk_product"; // We'll need this table joined to the select in order to filter by categ $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON p.rowid = pfp.fk_product"; // multilang if (! empty($conf->global->MAIN_MULTILANGS)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_lang as pl ON pl.fk_product = p.rowid AND pl.lang = '".$langs->getDefaultLang() ."'"; @@ -333,8 +335,30 @@ if ($search_vatrate) $sql .= natural_search('p.tva_tx', $search_vatrate); if (dol_strlen($canvas) > 0) $sql.= " AND p.canvas = '".$db->escape($canvas)."'"; if ($catid > 0) $sql.= " AND cp.fk_categorie = ".$catid; if ($catid == -2) $sql.= " AND cp.fk_categorie IS NULL"; -if ($search_categ > 0) $sql.= " AND cp.fk_categorie = ".$db->escape($search_categ); -if ($search_categ == -2) $sql.= " AND cp.fk_categorie IS NULL"; +$searchCategoryProductSqlList = array(); +if ($searchCategoryProductOperator == 1) { + foreach ($searchCategoryProductList as $searchCategoryProduct) { + if (intval($searchCategoryProduct) == -2) { + $searchCategoryProductSqlList[] = "cp.fk_categorie IS NULL"; + } elseif (intval($searchCategoryProduct) > 0) { + $searchCategoryProductSqlList[] = "cp.fk_categorie = " . $db->escape($searchCategoryProduct); + } + } + if (!empty($searchCategoryProductSqlList)) { + $sql .= " AND (" . implode(' OR ', $searchCategoryProductSqlList) . ")"; + } +} else { + foreach ($searchCategoryProductList as $searchCategoryProduct) { + if (intval($searchCategoryProduct) == -2) { + $searchCategoryProductSqlList[] = "cp.fk_categorie IS NULL"; + } elseif (intval($searchCategoryProduct) > 0) { + $searchCategoryProductSqlList[] = "p.rowid IN (SELECT fk_product FROM " . MAIN_DB_PREFIX . "categorie_product WHERE fk_categorie = " . $searchCategoryProduct . ")"; + } + } + if (!empty($searchCategoryProductSqlList)) { + $sql .= " AND (" . implode(' AND ', $searchCategoryProductSqlList) . ")"; + } +} if ($fourn_id > 0) $sql.= " AND pfp.fk_soc = ".$fourn_id; if ($search_tobatch != '' && $search_tobatch >= 0) $sql.= " AND p.tobatch = ".$db->escape($search_tobatch); if ($search_accountancy_code_sell) $sql.= natural_search('p.accountancy_code_sell', $search_accountancy_code_sell); @@ -421,7 +445,10 @@ if ($resql) if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.urlencode($contextpage); if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.urlencode($limit); if ($sall) $param.="&sall=".urlencode($sall); - if ($search_categ > 0) $param.="&search_categ=".urlencode($search_categ); + if ($searchCategoryProductOperator == 1) $param .= "&search_category_product_operator=" . urlencode($searchCategoryProductOperator); + foreach ($searchCategoryProductList as $searchCategoryProduct) { + $param .= "&search_category_product_list[]=" . urlencode($searchCategoryProduct); + } if ($search_ref) $param="&search_ref=".urlencode($search_ref); if ($search_ref_supplier) $param="&search_ref_supplier=".urlencode($search_ref_supplier); if ($search_barcode) $param.=($search_barcode?"&search_barcode=".urlencode($search_barcode):""); @@ -430,7 +457,7 @@ if ($resql) if ($search_tobuy != '') $param.="&search_tobuy=".urlencode($search_tobuy); if ($search_vatrate) $sql .= natural_search('p.tva_tx', $search_vatrate); if ($fourn_id > 0) $param.=($fourn_id?"&fourn_id=".$fourn_id:""); - if ($seach_categ) $param.=($search_categ?"&search_categ=".urlencode($search_categ):""); + //if ($seach_categ) $param.=($search_categ?"&search_categ=".urlencode($search_categ):""); if ($show_childproducts) $param.=($show_childproducts?"&search_show_childproducts=".urlencode($show_childproducts):""); if ($type != '') $param.='&type='.urlencode($type); if ($search_type != '') $param.='&search_type='.urlencode($search_type); @@ -465,7 +492,7 @@ if ($resql) $label='NewProduct'; if($type == Product::TYPE_SERVICE) $label='NewService'; $newcardbutton.= dolGetButtonTitle($langs->trans($label), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/product/card.php?action=create&type='.$type); - } + } print '
'; if ($optioncss != '') print ''; @@ -507,8 +534,11 @@ if ($resql) { $moreforfilter.='
'; $moreforfilter.=$langs->trans('Categories'). ': '; - $moreforfilter.=$htmlother->select_categories(Categorie::TYPE_PRODUCT, $search_categ, 'search_categ', 1); - $moreforfilter.='
'; + $categoriesProductArr = $form->select_all_categories(Categorie::TYPE_PRODUCT, '', '', 64, 0, 1); + $categoriesProductArr[-2] = '- ' . $langs->trans('NotCategorized') . ' -'; + $moreforfilter.=Form::multiselectarray('search_category_product_list', $categoriesProductArr, $searchCategoryProductList, 0, 0, 'minwidth300'); + $moreforfilter.=' ' . $langs->trans('or'); + $moreforfilter.=''; } //Show/hide child products. Hidden by default From 08f056a0f44d3427494a666b193eeabe710a1b40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sat, 14 Sep 2019 09:09:41 +0200 Subject: [PATCH 08/12] Delete interface_50_modIFTTT_IFTTT.class.php IFTTT has been removed --- .../interface_50_modIFTTT_IFTTT.class.php | 147 ------------------ 1 file changed, 147 deletions(-) delete mode 100644 htdocs/core/triggers/interface_50_modIFTTT_IFTTT.class.php diff --git a/htdocs/core/triggers/interface_50_modIFTTT_IFTTT.class.php b/htdocs/core/triggers/interface_50_modIFTTT_IFTTT.class.php deleted file mode 100644 index c7ce8f121fc..00000000000 --- a/htdocs/core/triggers/interface_50_modIFTTT_IFTTT.class.php +++ /dev/null @@ -1,147 +0,0 @@ - - * 2016 Christophe Battarel - * - * 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 . - */ - -/** - * \file htdocs/core/triggers/interface_50_modIFTTT_IFTTT.class.php - * \ingroup core - * \brief File of trigger for IFTTT module - */ -require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php'; - - -/** - * Class of triggers for IFTTT module - */ -class InterfaceIFTTT extends DolibarrTriggers -{ - /** - * @var DoliDB Database handler. - */ - public $db; - - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - public function __construct($db) - { - $this->db = $db; - - $this->name = preg_replace('/^Interface/i', '', get_class($this)); - $this->family = "ifttt"; - $this->description = "Triggers of the module IFTTT"; - $this->version = 'dolibarr'; // 'development', 'experimental', 'dolibarr' or version - $this->picto = 'ifttt'; - } - - /** - * Return name of trigger file - * - * @return string Name of trigger file - */ - public function getName() - { - return $this->name; - } - - /** - * Return description of trigger file - * - * @return string Description of trigger file - */ - public function getDesc() - { - return $this->description; - } - - /** - * Return version of trigger file - * - * @return string Version of trigger file - */ - public function getVersion() - { - global $langs; - $langs->load("admin"); - - if ($this->version == 'development') { - return $langs->trans("Development"); - } elseif ($this->version == 'experimental') { - return $langs->trans("Experimental"); - } elseif ($this->version == 'dolibarr') { - return DOL_VERSION; - } elseif ($this->version) { - return $this->version; - } else { - return $langs->trans("Unknown"); - } - } - - /** - * Function called when a Dolibarrr business event is done. - * All functions "runTrigger" are triggered if file is inside directory htdocs/core/triggers - * - * @param string $action Event action code - * @param Object $object Object - * @param User $user Object user - * @param Translate $langs Object langs - * @param conf $conf Object conf - * @return int <0 if KO, 0 if no triggered ran, >0 if OK - */ - public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf) - { - $ok = 0; - - if (empty($conf->ifttt->enabled)) return 0; // Module not active, we do nothing - - switch ($action) { - case 'THIRDPARTY_CREATED': - dol_syslog("Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id); - - include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php'; - - // See https://platform.ifttt.com/docs/api_reference#realtime-api - - $arrayofdata=array(); - $arrayofdata['user_id']=$conf->global->IFTTT_USER_ID; - $arrayofdata['trigger_identity']=$conf->global->IFTTT_TRIGGER_IDENTITY; - $arrayofdata['name']='testabcdef'; - $arrayofdata['email']='testemailabcdef'; - - $url = 'https://realtime.ifttt.com/v1/notifications'; - - $addheaders=array( - 'IFTTT-Service-Key'=>'123', - 'Accept'=>'application/json', - 'Accept-Charset'=>'utf-8', - 'Accept-Encoding'=>'gzip, deflate', - 'Content-Type'=>'application/json', - 'X-Request-ID'=>getRandomPassword(true, null) - ); - - $result = getURLContent($url, 'POSTALREADYFORMATED', '', 1, $addheaders); - - $ok = 1; - break; - } - - return $ok; - } -} From 7965804a34edf52bc8673a1b1975e1fc9d794f43 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 14 Sep 2019 16:35:00 +0200 Subject: [PATCH 09/12] Update ldap_groups.php --- htdocs/admin/ldap_groups.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/ldap_groups.php b/htdocs/admin/ldap_groups.php index 6dcc26a23e0..6412d2f6a59 100644 --- a/htdocs/admin/ldap_groups.php +++ b/htdocs/admin/ldap_groups.php @@ -58,7 +58,7 @@ if ($action == 'setvalue' && $user->admin) //if (! dolibarr_set_const($db, 'LDAP_GROUP_FIELD_NAME',$_POST["fieldname"],'chaine',0,'',$conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_GROUP_FIELD_DESCRIPTION', GETPOST("fielddescription"), 'chaine', 0, '', $conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_GROUP_FIELD_GROUPMEMBERS', GETPOST("fieldgroupmembers"), 'chaine', 0, '', $conf->entity)) $error++; - if (! dolibarr_set_const($db, 'LDAP_FIELD_GROUPID', GETPOST("fieldgroupid"), 'chaine', 0, '', $conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_GROUP_FIELD_GROUPID', GETPOST("fieldgroupid"), 'chaine', 0, '', $conf->entity)) $error++; // This one must be after the others $valkey=''; From 9934f73574d32d8b51825a2407c674112f6e13a6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 14 Sep 2019 16:36:04 +0200 Subject: [PATCH 10/12] Update ldap_groups.php --- htdocs/admin/ldap_groups.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/ldap_groups.php b/htdocs/admin/ldap_groups.php index 6412d2f6a59..8ae918ce180 100644 --- a/htdocs/admin/ldap_groups.php +++ b/htdocs/admin/ldap_groups.php @@ -173,7 +173,7 @@ print ''; // Group id print ''.$langs->trans("LDAPFieldGroupid").''; -print ''; +print ''; print ''.$langs->trans("LDAPFieldGroupidExample").''; print ' '; print ''; From d380ef1812535ea1adc2fdc571bf61a8d1d10e54 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 14 Sep 2019 16:37:07 +0200 Subject: [PATCH 11/12] Update usergroup.class.php --- htdocs/user/class/usergroup.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/user/class/usergroup.class.php b/htdocs/user/class/usergroup.class.php index 03c514f79f3..a89126b122f 100644 --- a/htdocs/user/class/usergroup.class.php +++ b/htdocs/user/class/usergroup.class.php @@ -980,8 +980,8 @@ class UserGroup extends CommonObject } $info[$conf->global->LDAP_GROUP_FIELD_GROUPMEMBERS] = (!empty($valueofldapfield)?$valueofldapfield:''); } - if(!empty($info[$conf->global->LDAP_FIELD_GROUPID])){ - $info[$conf->global->LDAP_FIELD_GROUPID]=$this->id; + if(!empty($info[$conf->global->LDAP_GROUP_FIELD_GROUPID])){ + $info[$conf->global->LDAP_GROUP_FIELD_GROUPID]=$this->id; } return $info; } From c015bbda14b79b0046d3ddeef356c66e4aa70daa Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 14 Sep 2019 16:39:08 +0200 Subject: [PATCH 12/12] Update ldap.class.php --- htdocs/core/class/ldap.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/ldap.class.php b/htdocs/core/class/ldap.class.php index 266b41867e8..267949e2149 100644 --- a/htdocs/core/class/ldap.class.php +++ b/htdocs/core/class/ldap.class.php @@ -609,7 +609,7 @@ class Ldap } if ($result <= 0) { - $this->error = ldap_errno($this->connection)." ".$this->error; + $this->error = ldap_error($this->connection).' (Code '.ldap_errno($this->connection).") ".$this->error; dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR); //print_r($info); return -1;